Xamarin.Forms JSON object into Listview Xamarin.Forms JSON object into Listview json json

Xamarin.Forms JSON object into Listview


Your async call is not correct. If you have to do it in the constructor (which isn't the best place to do this) you would want to use ContinueWith as using Task.Result should not be used. Also because the Result is a blocking call you are assigning the item source before the list view is constructed and you are getting a null reference exception.

Try this:

public class ListViewPage : ContentPage{    private readonly ListView listView;    public ListViewPage()    {        Title = "Users";        this.listView = new ListView {ItemTemplate = new DataTemplate(typeof (TextCell))};        this.listView.ItemTemplate.SetBinding(TextCell.TextProperty, "username");        Content = new StackLayout        {            Children = { this.listView }        };        var sv = new RestClient();        var es = sv.GetUsersAsync().ContinueWith(t =>        {            if (t.Status == TaskStatus.RanToCompletion)            {                Debug.WriteLine("Found {0} users.", t.Result.Length);                Device.BeginInvokeOnMainThread(() => this.listView.ItemsSource = t.Result);            }        });    }}

A slightly better option (but not perfect either) would be to override the appearing method and mark is async. This way you can use await on the async REST call method. Note that this would get called every time the view appears unless additional code is added.

    protected override async void OnAppearing()    {        base.OnAppearing();        try        {            var sv = new RestClient();            // activate/show spinner here            this.listView.ItemsSource = await sv.GetUsersAsync();            // inactivate/hide spinner here        }        catch (Exception exception)        {            this.DisplayAlert("Error", exception.Message, "OK");        }    }


Looks like you are not awaiting sv.GetUsersAsync and I'm not sure if Result will contain all data without waiting for the operation to be completed.

Though it's fine to use any collection and any objects as data source for list view it's better to use ObservableCollection and make your User class implement INotifyPropertyChanged (take a look on Fody.PropertyChanged nuget package).

Could you share xaml with us?

EDIT 1

You define your ItemTemplate twice.

listView.ItemTemplate = new DataTemplate(typeof(TextCell)); //first definitionlistView.ItemTemplate.SetBinding(TextCell.TextProperty, "username");listView.ItemTemplate = new DataTemplate(typeof(ItemCell)); //second definition, remove it

Plus it's better to use MVVM with Xamarin.Forms and load your data in view-model and not in your page's constructor. Here is good article about mvvm and data loading in Xamarin.Forms.

EDIT 2

Why do you use async/await in such a strange way? Instead of reading Task.Result property it's better to use async/await pair. Example.