I have a profile view-model that in it's constructor calls the DB for the user that just logged. It works fine but if I delay it by 3s then I assume one of the threads continues and creates the view with nothing inside. I use a data template selector to construct the view and if I delay the task then the view will not render anything. Again, if I don't delay it works fine but I need to make sure that it will work if the server takes longer to respond and 3s is not that much in some cases
here is my view model
public class ProfileViewModel: BaseViewModel
{
private ObservableCollection<Stylist> users;
public ObservableCollection<Stylist> Users
{
get => users;
set
{
users = value;
OnPropertyChanged();
}
}
private Stylist user;
public Stylist User { get => user; set { user = value; OnPropertyChanged(); } }
private bool isStylist;
public AsyncCommand TestCommand { get; set; }
public ProfileViewModel()
{
IsBusy = true;
TestCommand = new AsyncCommand(Test);
Users = new ObservableCollection<Stylist>();
Task.Run(async () =>
{
int id = ((App)App.Current).ID;
if (!((App)App.Current).IsStylist)
{
var user = await DB.GetUser(id);
User = CopyUserToStylist(user);
}
else User = await DB.GetStylist(id);
isStylist = User.IsStylist;
await Task.Delay(3000); // without this line everything is ok
Users.Add(User);
OnPropertyChanged(nameof(Users));
IsBusy = false;
});
}
the view
<ContentPage.Resources>
<DataTemplate x:Key="UserTemplate">
<StackLayout>
<Label Text="user logged"/>
<Label Text="{Binding Name}"/>
</StackLayout>
</DataTemplate>
<DataTemplate x:Key="StylistTemplate">
<StackLayout>
<Label Text="stylist logged"/>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Location}"/>
<Button Text="Test stylist"
Command="{Binding TestCommand}"/>
</StackLayout>
</DataTemplate>
<local:UserTypeSelector
x:Key="personDataTemplateSelector"
StylistTemplate="{StaticResource StylistTemplate}"
UserTemplate="{StaticResource UserTemplate}" />
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Margin="10"
BindableLayout.ItemTemplateSelector="{StaticResource personDataTemplateSelector}"
BindableLayout.ItemsSource="{Binding Users}">
<Label Text="FML"/>
<Label Text="Loading"
IsVisible="{Binding IsBusy}"/>
<Button Text="Test"
Command="{Binding TestCommand}"/>
</StackLayout>
</ContentPage.Content>
and the db calls
public static async Task<User> GetUser(int id)
{
await Init();
return await db.Table<User>().Where(x => x.id == id).FirstAsync();
}
public static async Task<Stylist> GetStylist(int id)
{
await Init();
return await db.Table<Stylist>().Where(x => x.id == id).FirstAsync();
}