LoginViewModel Prism Navigation return always Unhandled Exception: System.NullReferenceException

GentiGaceGentiGace ✭✭USMember ✭✭
edited July 30 in Xamarin.Forms

Hi everyone, this is my first post and I hope to find the right answer here.
I have created a login form that works very good but what I am trying to do is after a positive response I want to navigate to my Main Menu at this point I always receive Unhandled Exception:System.NullReferenceException: Object reference not set to an instance of an object.

LoginViewModel code:

class LoginViewModel : BindableBase
{
private readonly ApiServices _apiServices = new ApiServices();

    private INavigationService _navigationService;

    public LoginViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public string Email { get; set; }
    public string Password { get; set; }
    public ICommand LoginCommand
    {
        get
        {
            return new Command(async () =>
            {
                var accesstoken = await _apiServices.LoginAsync(Email, Password);
                {
                    if (accesstoken != null)
                    {
                        await Prism.PrismApplicationBase.Current.MainPage.DisplayActionSheet("Thank you, you are logged in", "Ok", "");

                        Navigate();

                        void Navigate()
                        {
                            _navigationService.NavigateAsync("MainMenu");
                        }
                    }

                    else
                    {
                        await Prism.PrismApplicationBase.Current.MainPage.DisplayActionSheet("Please enter the correct credentials", "Ok", "");
                    }
                }

                Settings.AccessToken = accesstoken;
            });

        }
    }

    public LoginViewModel()
    {
        Email = Settings.Email;
        Password = Settings.Password;
    }
}

}

ApiService

    public async Task<string> LoginAsync(string userName, string password)
    {
        var keyValues = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("username", userName),
            new KeyValuePair<string, string>("password", password),
            new KeyValuePair<string, string>("grant_type", "password")
        };

        var request = new HttpRequestMessage(
            HttpMethod.Post, Constants.BaseApiAddress + "Token");

        request.Content = new FormUrlEncodedContent(keyValues);

        var client = new HttpClient();
        var response = await client.SendAsync(request);

        var content = await response.Content.ReadAsStringAsync();

        JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(content);

        var accessTokenExpiration = jwtDynamic.Value<DateTime>(".expires");
        var accessToken = jwtDynamic.Value<string>("access_token");

        Settings.AccessTokenExpirationDate = accessTokenExpiration;

        Debug.WriteLine(accessTokenExpiration);

        Debug.WriteLine(content);

        return accessToken;
    }


}

}

Tagged:

Best Answer

Answers

  • GentiGaceGentiGace ✭✭ USMember ✭✭

    Thank you NMackay for your fast response I will try to implement your suggestions and I will let you know if this suggestions are working.

  • GentiGaceGentiGace ✭✭ USMember ✭✭

    Hi NMackay your method does not work, I am posting also my login xaml because I think that the problem of navigation is the relation between
    <ContentPage.BindingContext>

    </ContentPage.BindingContext>

    and Prism Navigation

    I am posting also the full XAML

    <?xml version="1.0" encoding="utf-8" ?>

    <NavigationPage.TitleView>
        <Label Text="GNH Control" FontSize="12" TextColor="#D77927" />
    </NavigationPage.TitleView>
    
    <ContentPage.BindingContext>
        <viewModels:LoginViewModel/>
    </ContentPage.BindingContext>
    
    <ContentPage.Content>
        <StackLayout HorizontalOptions="Center"
                     VerticalOptions="Center"
                     Spacing="10"
                     Padding="20">
            <Image Source="GNHC_Logo_C.png" />
    
            <Entry Text="{Binding Email}" Placeholder="Email" FontSize="Small" TextColor="#D77927" WidthRequest="175"
                   PlaceholderColor="White"/>
    
            <Entry Text="{Binding Password}" IsPassword="True" Placeholder="Password" FontSize="Small" TextColor="#D77927"
                   PlaceholderColor="White"/>
    
            <Button Command ="{Binding LoginCommand}"
                    Text="Login" BackgroundColor="#212B34" CornerRadius="10" BorderColor="#D77927" BorderWidth="2" TextColor="#4D8352"
                FontSize="Default"/>
        </StackLayout>
    </ContentPage.Content>
    

  • NMackayNMackay mod GBInsider, University mod
    edited August 1

    I never said my suggestions would fix your problem, I simply showed you how your code should be structured so the navigation is done asynchronously and showed you a way to figure out how to what your issue was.

    What was the navigation result? Task should be faulted.

  • GentiGaceGentiGace ✭✭ USMember ✭✭

    Ok, I know but I try to replace the code with your suggestion but if you can see there is a relation between BindindContext and the constructor, if I will use your method I will break this relation and the button of login it doesn't work.

  • NMackayNMackay mod GBInsider, University mod

    I give up up, I have no idea what your on about.

Sign In or Register to comment.