Forum Xamarin.Forms

Products loaded from REST API, constructed in codebehind get loaded when OnAppearing isHitSecondtime

I load product from REST API in ViewModel and construct them in codebehind of the view.

Code for codebehind:

ProductsViewModel vm;
public ProductsPage ()
{
InitializeComponent ();
BindingContext = vm = new ProductsViewModel();
vm.Navigation = Navigation;
}

    protected async override void OnAppearing()
    {
        base.OnAppearing();

        // this loads products from REST API
        if (vm.Products.Count == 0)
            vm.LoadProductsCommand.Execute(null);

        Device.BeginInvokeOnMainThread(() =>
        {
            ProductGrid.Children.Clear();
        });

        // when products are loaded, this constructs those products
        if (!vm.IsBusy)
        {
            var grid = new Grid { Padding = 5, RowSpacing = 5, ColumnSpacing = 5 };
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star )});
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star )});

            grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(150) });

            var viewCell = new ViewCell();

            int column = 0;
            int row = 0;
            foreach(Product product in vm.Products)
            {

                var gridInner = new Grid();
                gridInner.RowDefinitions.Add(new RowDefinition { Height = new GridLength(4, GridUnitType.Star) });
                gridInner.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25) });
                // the rest of code is product construction and adding them to list

ViewModel constructor, where command is set:

            public ProductsViewModel()
            {
                ...
                LoadProductsCommand = new Command(async () => await ExecuteLoadProductsCommand());
                ...
            }

Function where products are being loaded:

async Task ExecuteLoadProductsCommand()
        {
            if (IsBusy)
                return;
            IsBusy = true;
            try
            {
                Products.Clear();
                var products = await _productService.GetProductsAsync();
                foreach(Product product in products)
                {
                    Products.Add(product);
                }
            }
            catch(Exception e)
            {
                Debug.WriteLine(e);
            }
            finally
            {
                IsBusy = false;
            }
        }

Ok. Now I know what the problem is. In codebehind, when if(!vm.isBusy) is behind hit, httpclient is still loading data, so IsBusy is set to false. But how do I tell codebehind, Ok data is now loaded, IsBusy is set to true, construct products and display them on the view? In XAML this is being done on it's own, how do I do it in code behind?

Best Answer

Answers

Sign In or Register to comment.