Indicate App State

The top-level view model will typically indicate the state of the application. This includes notifying the user of an error, displaying the health of the connection, and asking them to log in again.

The root view (sometimes called AppShell) handles OnAppearing and OnDisappering to load and unload the view model. When loading the AppShellViewModel, add a listener to the JinagaClient for OnStatusChanged.

public void Load()
{
    jinagaClient.OnStatusChanged += JinagaClient_OnStatusChanged;
}

public void Unload()
{
    jinagaClient.OnStatusChanged -= JinagaClient_OnStatusChanged;
}

In the JinagaClient_OnStatusChanged method, respond to the status by setting observable properties. Design the indicators to best fit your application.

Saving Status

  • bool IsSaving
  • Exception? LastSaveError
  • int QueueLength

When the Jinaga client is sending a fact to the replicator, the status will indicate that the app is saving. If an error occurs during that process, the status will give you the exception.

The status will also indicate the number of facts in the outgoing queue. If the client is not saving, and there are facts in the queue, then there is unsaved data in the app. You will typically want to prioritize this status to show to the user.

private void JinagaClient_OnStatusChanged(JinagaStatus status)
{
    if ((!status.IsSaving || status.LastSaveError != null) && status.QueueLength > 0)
    {
        // There are facts in the queue, and
        // the client is not saving, or has
        // experienced an error.
        Status = "Red";
        if (status.LastSaveError != null)
        {
            Error = status.LastSaveError.GetMessage();
        }
    }
}

Loading Status

  • bool IsLoading
  • Exception? LastLoadError

When the Jinaga client is fetching from a feed, the status will indicate that the app is loading. If an error occurs during that process, the status will give you the exception.

private void JinagaClient_OnStatusChanged(JinagaStatus status)
{
    Busy = status.IsLoading || status.IsSaving;

    if ( ... )
    {
        // Indicate saving errors
    }
    else if (status.LastLoadError != null)
    {
        // The client has experienced an error on load.
        Status = "Yellow";
        Error = status.LastLoadError.GetMessage();
    }
    else
    {
        Status = "Green";
        Error = string.Empty;
    }
}

Authentication State

The JinagaStatus parameter provides an AuthenticationState property, which has the following values:

  • NotAuthenticated
  • Authenticated
  • AuthenticationExpired

The NotAuthenticated and Authenticated states tell you whether the user is logged in. The AuthenticationExpired state tells you that the user was logged in, but the token has expired. You will typically want to respond to this state by asking the user to log in again.

private void JinagaClient_OnStatusChanged(JinagaStatus status)
{
    if (status.AuthenticationState == AuthenticationState.AuthenticationExpired)
    {
        NavigateToLogin = true;
    }
}

As with all status indicators, you should set an observable property. Let the view bind to that property to show the user what is happening and take appropriate action. Do not simply navigate to the login page from the view model when their authentication expires, because that would provide a poor user experience in an offline scenario.

Continue With

Define Authorization Rules

Jinaga is a product of Jinaga LLC.

Michael L Perry, President