Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 89864

Object reference not set to an instance of an object

$
0
0

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);
        }
    }
}

Viewing all articles
Browse latest Browse all 89864

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>