Issue
I have a database like this up on firebase realtime db:
->petProfiles
->Node
->UserEmail
->PetName
->Breed
->Node
->UserEmail
->PetName
->Breed
->Node
->UserEmail
->PetName
->Breed
I would like to bind this data to make a list view however I just want to use the branches which have the same UserEmail (just show the loggedin users pets to them in a list view). However no data appears on screen. I think i'm populating my ObservableCollection wrong. Could you please give me some pointers.
viewmodel:
class MyIDPageViewModel : INotifyPropertyChanged
{
FirebaseHelper firebaseHelper = new FirebaseHelper();
readonly IList<PetProfile> source;
public ObservableCollection<PetProfile> PetInfo { get; private set; }
public IList<PetProfile> EmptyPetInfo { get; private set; }
public MyIDPageViewModel()
{
source = new List<PetProfile>();
CreatePetProfileCollection();
OnPropertyChanged();
}
private async void CreatePetProfileCollection()
{
var petProfiles = await firebaseHelper.GetAllUserPetInfos();
if(petProfiles != null)
{
foreach (var groupitems in petProfiles)
{
source.Add(new PetProfile() { PetName = groupitems.PetName });
}
}
PetInfo = new ObservableCollection<PetProfile>(source);
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
''' Firebasehelper:
public async Task<List<PetProfile>> GetAllUserPetInfos()
{
var useremail = Preferences.Get("UserSignInEmail", "");
var PetProfiles = await GetAllPetInfos();
await firebase
.Child("PetProfiles")
.OnceAsync<PetProfile>();
return PetProfiles.Where(a => a.UserEmail == useremail).ToList();
}
Solution
There are two ways to go about this and there is one way why it isnt working ;)
So why does it not work?
Eventhought you're implementing the INotifyPropertyChanged interface, you are never actually invoking the event. PropertyChangedEventHandler delegates added to the PropertyChanged event have to be invoked manually.
When doing
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
You're doing that, however you're not calling OnPropertyChanged anywhere in your code.
So how can you solve that issue.
1.
public IList<PetProfile> EmptyPetInfo {
get => source;
private set {
if (value != source) {
source = value;
OnPropertyChanged(nameof(EmptyPetInfo));
}
}
}
Call OnPropertyChanged in the setter of your ObservableCollection.
2.
private async void CreatePetProfileCollection()
{
var petProfiles = await firebaseHelper.GetAllUserPetInfos();
if(petProfiles != null)
{
PetInfo = new ObservableCollection<PetProfile>();
foreach (var groupitems in petProfiles)
{
PetInfo.Add(new PetProfile() { PetName = groupitems.PetName });
}
}
}
Add the objects to the ObservableCollection instead.
Edit: Missed to see that you are calling OnPropertyChanged without an argument from from your constructor. You have to provide the name of the property that you wish to have its value updated in the view.
Before calling OnPropertyChanged thought u are also executing an asynchronous method. The moment you are calling an asynchronous method, it is started on a new thread and the execution inside your constructor continues. Therefore OnPropertyChanged will be called, before you even received the realtime data.
Answered By - VocalTrance
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.