0

So my code works in PostMan querying the api to populate a listview locally in my Android app. But when I run it from within the app, I get NullReferenceException on the line "Items.Clear() in ShipViewModel.cs

I tried hardcoding the address rather than using my APIQueriable path, I tried generating new JWT, and I tried manually cleaning my /bin /obj folders to rule out code not compiling correctly.

ShipsViewModel.cs Xamarin.Forms/ViewModels

    {
        private GallogClient _gallogClient;
        public ObservableCollection<ShipCatalog> Items { get; set; }
        public Command LoadItemsCommand { get; }

        public ShipsViewModel()
        {
            Title = "Ships";
            _gallogClient = new GallogClient("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkuZ2FsbG9nLmNvIiwiYXVkIjoiaHR0cDpcL1wvYXBpLmdhbGxvZy5jbyIsImlhdCI6MTM1Njk5OTUyNCwibmJmIjoxMzU3MDAwMDAwLCJkYXRhIjp7ImlkIjo1NywidXNlcm5hbWUiOiJQYXJhIiwiaGFuZGxlIjoiUGFyYSIsImVtYWlsIjoicGFyYWJvbGE5NDlAZ21haWwuY29tIn19.bRpI9hVy-Spky5pbZhJCkyN-MT9RA6ap_yD9ezRxCxo");
            LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand(), () => !IsBusy);
        }
        async Task ExecuteLoadItemsCommand()
        {
            if (IsBusy)
                return;

            IsBusy = true;

            try
            {
                LoadItemsCommand.ChangeCanExecute();
                Items.Clear();
                var items = await _gallogClient.GetItemsAsync<ShipList>();
                foreach (var item in items.ships.ToList())
                {
                    Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }

    }

}

GallogClient.cs Gallog.API

    {
        internal readonly HttpClient Client = new HttpClient { BaseAddress = new Uri("https://api.gallog.co/api/") };

        public string Jwt { get; set; }
        public GallogClient()
        {

        }

        public GallogClient(string jwt)
        {
            Jwt = jwt;
        }

        private StringContent JwtContent
        {
            get {
                return new StringContent(JsonConvert.SerializeObject(new
                {
                    jwt = Jwt              
                }), Encoding.UTF8, "application/json");
            }
        }

            //...

        public async Task<T> GetItemAsync<T>(string name) where T : ApiQueryable
        {
            return await PostAsync<T>($"{GetPath<T>()}/{name}");
        }


        public async Task<T> GetItemsAsync<T>() where T : ApiQueryable
        {
            return await PostAsync<T>($"{GetPath<T>()}");
        }

        internal string GetPath<T>()
        {
            if (typeof(T).GetCustomAttributes(
                typeof(ApiPathAttribute), true
            ).FirstOrDefault() is ApiPathAttribute at)
            {
                return at.Path;
            }
            return null;
        }

        public async Task<T> PostAsync<T>(string path) where T : ApiQueryable
        {
            var response = await Client.PostAsync(path, JwtContent);
            return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
        }

        public async Task<T> PostAsync<T>(object body, string path) where T : ApiQueryable
        {
            var response = await Client.PostAsync(path,
                new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"));
            return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
        }
    }
}

ShipList.cs Xamarin.Forms/Models

{
    [ApiPath("ships")]
    public class ShipList : ApiQueryable
    {
        public ShipCatalog[] ships { get; set; }
    }

    public class ShipCatalog
    {
        public int id { get; set; }
        public string name { get; set; }
      //  ...etc etc
    }  



}

1 Answers1

1

Items is null because you declared it but have never initialized it

public ShipsViewModel()
{
    ...
    Items = new ObservableCollection<ShipCatalog>();
    ...
}
Jason
  • 86,222
  • 15
  • 131
  • 146