Object reference not set to an instance of an object

I am currently making an app to display and interact with a company's employees. I have a list of departments and when a department is selected, I am trying to show only a list of employees in that department. I am pulling the departments and employees from two different JSON urls. I am trying to use linq to pull the employees where the department is the same as the selected department. I am using James Montemagno's Monkey Finder workshop to help build my app. However, when I try to load the contacts I get an object reference not set to an instance of an object error. I will put my code below for reference on what I am doing as well as screenshots of the error. Does anyone know how to fix this or what I am doing wrong? Thank you!

App Screenshots:

Code:

Model:

Contact.cs

using System;
using System.Collections.Generic;

using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace ContactNavigation.Model
{
    public partial class Contact
    {
        [JsonProperty("FirstName")]
        public string FirstName { get; set; }

        [JsonProperty("LastName")]
        public string LastName { get; set; }

        [JsonProperty("Department")]
        public string Department { get; set; }

        [JsonProperty("Position")]
        public string Position { get; set; }

        [JsonProperty("PhoneNumber")]
        public string PhoneNumber { get; set; }

        [JsonProperty("Email")]
        public string Email { get; set; }

        [JsonProperty("Picture")]
        public Uri Picture { get; set; }

        [Newtonsoft.Json.JsonIgnore]
        public string FullName { get { return FirstName + " " + LastName; } }
    }

    public partial class Contact
    {
        public static Contact[] FromJson(string json) => JsonConvert.DeserializeObject<Contact[]>(json, ContactNavigation.Model.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Contact[] self) => JsonConvert.SerializeObject(self, ContactNavigation.Model.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}

Services:

IDataService.cs

using ContactNavigation.Model;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace ContactNavigation.Services
{
    public interface IDataService
    {
        Task<IEnumerable<Contact>> GetContactsAsync();

        Task<IEnumerable<Department>> GetDepartmentsAsync();
    }
}

WebDataService

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;
using Newtonsoft.Json;
using System.Text;
using System;
using System.Linq;
using ContactNavigation.Model;
using ContactNavigation.Services;


[assembly: Dependency(typeof(WebDataService))]
namespace ContactNavigation.Services
{
    public class WebDataService : IDataService
    {
        HttpClient DepartmentsHttpClient;
        HttpClient DepartmentClient => DepartmentsHttpClient ?? (DepartmentsHttpClient = new HttpClient());

        HttpClient ContactsHttpClient;

        HttpClient ContactClient => ContactsHttpClient ?? (ContactsHttpClient = new HttpClient());

        public async Task<IEnumerable<Contact>> GetContactsAsync()
        {
            var json = await ContactClient.GetStringAsync("MyContactURLHere");
            var all = Contact.FromJson(json);
            return all;
        }

        public async Task<IEnumerable<Department>> GetDepartmentsAsync()
        {
            var json = await DepartmentClient.GetStringAsync("MyDepartmentURLHere");
            var all = Department.FromJson(json);
            return all;
        }
    }
}

ViewModel:

ContactViewModel.cs

using ContactNavigation.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Diagnostics;

namespace ContactNavigation.ViewModel
{
    public class ContactViewModel : BaseViewModel
    {
        public ObservableCollection<Contact> EmployeeContacts { get; }

        public Command GetContactsCommand { get; }

        public ContactViewModel()
        {
            GetContactsCommand = new Command(async () => await GetContactsAsync());
        }

        public ContactViewModel(Department department)
            : this()
        {
            Department = department;
            Title = $"{Department.DepartmentName}";

        }
        Department department;
        public Department Department
        {
            get => department;
            set
            {
                if (department == value)
                    return;

                department = value;
                OnPropertyChanged();
            }
        }

        async Task GetContactsAsync()
        {
            if (IsBusy)
                return;

            try
            {
                IsBusy = true;

                var contacts = await DataService.GetContactsAsync();

                EmployeeContacts.Clear();
                foreach (var contact in contacts.Where(x => x.Department == department.DepartmentName))
                    EmployeeContacts.Add(contact);
            }
            catch(Exception ex)
            {
                await Application.Current.MainPage.DisplayAlert("Error!", ex.Message, "OK");
            }
            finally
            {
                IsBusy = false;
            }
        }
    }
}

View:
ContactPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             xmlns:local="clr-namespace:ContactNavigation"
             xmlns:viewmodel="clr-namespace:ContactNavigation.ViewModel"
             xmlns:circle="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
             xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
             x:Class="ContactNavigation.View.ContactPage"
             ios:Page.UseSafeArea="True"
             Title="{Binding Title}"
             BackgroundColor="#57565B">
    <ContentPage.BindingContext>
        <viewmodel:ContactViewModel/>
    </ContentPage.BindingContext>
    <Grid RowSpacing="0" ColumnSpacing="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ListView ItemsSource="{Binding EmployeeContacts}"
                  CachingStrategy="RecycleElement"
                  HasUnevenRows="True"
                  Grid.ColumnSpan="2">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid ColumnSpacing="10" 
                              Padding="10">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="60"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <circle:CircleImage Source="{Binding Picture}"
                                                HorizontalOptions="Center"
                                                VerticalOptions="Center"
                                                BorderColor="{StaticResource PrimaryDark}"
                                                BorderThickness="3"
                                                WidthRequest="60"
                                                HeightRequest="60"
                                                Aspect="AspectFill"/>
                            <StackLayout Grid.Column="1"
                                         VerticalOptions="Center">
                                <Label Text="{Binding FullName}"
                                       TextColor="White"/>
                                <Label Text="{Binding Position}"
                                       TextColor="White"/>
                            </StackLayout>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Text="Load Contacts"
                TextColor="White"
                BackgroundColor="{StaticResource PrimaryDark}"
                Command="{Binding GetContactsCommand}"
                IsEnabled="{Binding IsNotBusy}"
                Grid.Row="1"
                Grid.Column="0"
                Grid.ColumnSpan="2"/>
        <ActivityIndicator IsVisible="{Binding IsBusy}"
                           IsRunning="{Binding IsBusy}"
                           HorizontalOptions="FillAndExpand"
                           VerticalOptions="CenterAndExpand"
                           Grid.RowSpan="2"
                           Grid.ColumnSpan="2"/>
    </Grid>
</ContentPage>

ContactPage.xaml.cs

using ContactNavigation.Model;
using ContactNavigation.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ContactNavigation.View
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class ContactPage : ContentPage
    {
        public ContactPage()
        {
            InitializeComponent();
        }

        public ContactPage(Department department)
        {
            InitializeComponent();
            BindingContext = new ContactViewModel(department);
        }
    }
}

Posts

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    you should try to understand the row where you have the problem. Try to debug your code

  • JohnHardmanJohnHardman GBUniversity mod

    @grayson_alexander

    You have a null reference exception occurring. Either using the debugger, or simply checking the stack trace in the Output window, which line of code is throwing the exception?

  • grayson_alexandergrayson_alexander Member ✭✭

    @AlessandroCaliaro @JohnHardman I have been trying to put in various break points to determine where the exception is happening. On my EmployeeContacts.Clear() line I noticed that EmployeeContacts is null and I don't think that should be the case. I have similar code to in my DepartmentViewModel to load the departments and on my EmployeeDepartments.Clear() line EmployeeDepartments has a count of 0. So it isn't null. I'm not sure why one is null and the other is working.

  • JohnHJohnH GBMember ✭✭✭✭✭

    @grayson_alexander said:
    @AlessandroCaliaro @JohnHardman I have been trying to put in various break points to determine where the exception is happening. On my EmployeeContacts.Clear() line I noticed that EmployeeContacts is null and I don't think that should be the case. I have similar code to in my DepartmentViewModel to load the departments and on my EmployeeDepartments.Clear() line EmployeeDepartments has a count of 0. So it isn't null. I'm not sure why one is null and the other is working.

    You aren't setting EmployeeContacts, so it will always be null. Initialize it as a new ObservableCollection.

  • grayson_alexandergrayson_alexander Member ✭✭

    @JohnHardman That fixed it! Thank you so much!

Sign In or Register to comment.