Lesson 19

Improving User Experience

User experience improvements for the application

PRO

Lesson Outline

Improving User Experience

We are just about finished with the application now, but as I mentioned before, we want to go the extra mile and focus on the little details in the application that will do a great deal to improve user experience.

I don't want to pay too much attention to discussing user experience concepts and the rationale of why we are making certain changes, as a lot of that is covered in detail in the User Interface and User Experience module in this course. I will try to keep it brief and focus on implementing the changes (because we will be making quite a few).

Let's get into it!

Disable Buttons for Invalid Forms

The first change is going to be a subtle improvement, but it will help guide the user and it will also make things a bit easier for us. We are going to modify all of the buttons in our application that submit forms so that they are disabled until the form is valid. This will prevent the user from clicking the button if certain conditions are not met, and it will also apply visual styling to the button to indicate that the button is not active. All we need to do to achieve this is to toggle the built-in disabled attribute.

Modify the Log In button in src/app/login/login.page.html to refect the following:

<ion-button
  [disabled]="!(username.length > 0 && password.length > 0)"
  color="light"
  fill="outline"
  class="login-button"
  (click)="login()"
>
  <ion-icon slot="end" name="log-in"></ion-icon> Log In
</ion-button>

This will disable the login button if the user has not entered both a username and password.

Modify the Create Account button in src/app/register/register.page.html to reflect the following:

<ion-button
  [disabled]="!registerForm.valid"
  expand="full"
  color="light"
  class="register-button"
  (click)="createAccount()"
>
  Create Account <ion-icon slot="end" name="arrow-forward"></ion-icon>
</ion-button>

Since we are using the FormBuilder to create our register form, all we have to do is check the valid property on the form. If the form is not valid, we disable the button.

Modify the Add Chat button in src/app/chat/chat.page.html to reflect the following:

<ion-button
  [disabled]="message.length === 0"
  (click)="addChat()"
  class="send-chat-button"
>
  <ion-icon slot="icon-only" name="send"></ion-icon>
</ion-button>

For the chat button, we check if there is a message entered into the message field.

Modify the Save Notice button in src/app/add-notice/add-notice.page.html to reflect the following:

<ion-button
  [disabled]="title.length === 0"
  class="save-notice-button"
  color="primary"
  expand="full"
  (click)="saveNotice()"
>
  Save Notice
</ion-button>

When adding a notice the user can add a title field and a message field, but we only enforce that a title is entered, so we do the same here for disabling the button.

Improving User Feedback for Forms

We've already implemented some measures for giving feedback to the user when filling out forms, but we are going to add a couple of extra details now.

When we implemented our asynchronous username and email validators we also set up an error message that will be displayed to the user should these validations fail. However, since these are asynchronous this may take a couple of seconds to happen, and during that time the user might assume that the field was entered correctly only for it to change on them.

To combat this, we are going to add a loading indicator to our email and username fields to indicate to the user that the field is currently being checked. In order to do this, we are going to update our Error Messages component.

Modify src/components/error-messages/error-messages.component.html to reflect the following:

<div class="async-pending" *ngIf="control.pending">
  <ion-spinner></ion-spinner>
  Checking...
</div>
<div *ngIf="errorMessage !== null">
  <ul>
    <li>{{errorMessage}}</li>
  </ul>
</div>

This adds a conditional element to the template, which will only display if control.pending is true. The pending property on the control will be true if an asynchronous validator is currently executing, so the spinner will display whilst our username and email fields are checking against the server.

So that this displays properly, we are also going to add some styling to it.

Modify src/components/error-messages/error-messages.scss to reflect the following:

ion-spinner {
  height: 20px;
  width: 20px;
  margin-right: 5px;
}

.async-pending {
  display: flex;
  align-items: center;
  height: 20px;
  font-weight: normal;
}

ul {
  margin: 0;
  padding-left: 20px;
  padding-bottom: 5px;
  color: var(--ion-color-dark);
}

Now when the asynchronous validation is in progress the user should see the spinning animation.

We're going to add one more form related improvement for the login screen. Right now, we display an error message to the user for a failed login attempt. However, it just pops in instantly and it's possible that the user could miss it and not realise what is happening.

PRO

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).