Jerry's Blog

Recording what I learned everyday

View on GitHub


4 July 2019

Angular (21) -- Loading Spinners

by Jerry Zhang

Day 28: Loading Spinners

Loading Spinners

Search “css loading spinners” and there is a website “loading.io” which has many loading css animation.

Create a new component, loading-spinner. In the css file, we copy the css code from the website and change the color to whatever we like. And also copy the html code to our html file in this component.

Replacing the Content with a Loading Spinner

In the auth component, we add a new property called isLoading = false. Before we send the http request, we set this property to true.

onSubmit(f: NgForm) {
    if (!f.valid) {
      return;
    }
    const email = f.value.email;
    const password = f.value.password;
    this.isLoading = true;
    if (this.isLoginMode) {
      // ...
    } else {
      this.authService.signup(email, password).subscribe(resData => {
        console.log(resData);
        this.isLoading = false;
      }, errorRes => {
        console.log(errorRes);
        switch (errorRes.error.error.message) {
          case 'EMAIL_EXISTS':
            this.error = 'This email exists already';
        }
        this.isLoading = false;
      });
    }

    f.reset();
  }

Then the isLoading property can be used in the template to hide the form with *ngIf. The form will appear only if it is not loading, and will be replaced by the loading spinner when it is loading.

<div *ngIf="isLoading" style="text-align: center">
  <app-loading-spinner></app-loading-spinner>
</div>
<form #f="ngForm" (ngSubmit)="onSubmit(f)" *ngIf="!isLoading">

Handling the error

In the auth component, we add a new property called error: string = null;.

In the auth component, we add a new alert div.

<div class="alert alert-danger" *ngIf="error">
  <p></p>
</div>

We could use switch... case to check each type of error message, but that is not convenient to put all these logic in the component. Instead, we’d better to use a rxjs/operator to check it in the service. Here, we use catchError operator and throwError which will create a new Observable that wraps an error.

@Injectable({providedIn: 'root'})
export class AuthService {

  constructor(private http: HttpClient) {}

  signup(email: string, password: string) {
    return this.http.post<AuthResponseData>(
      'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=AIzaSyCQUonbyGcWNNCk-jS2WWkgpR3U0TtkIdA',
      {
        email: email,
        password: password,
        returnSecureToken: true
      }
    ).pipe(catchError(errorRes => {
      let errorMessage = 'An unknown error occurred!';
      if (!errorRes.error || !errorRes.error.error) {
        return throwError(errorMessage);
      }
      switch (errorRes.error.error.message) {
        case 'EMAIL_EXISTS':
          errorMessage = 'This email exists already';
      }
      return throwError(errorMessage);
    }));
  }
}

tags: Angular