Create button spinner when clicked in angular 5

18,449

Solution 1

HttpModule is deprecated you must use the new HttpClientModule whcih by default formats the response to JSON so we no longer need to parse it using response.json():

Revised service code: Return Observable from your service and subscribe it in your component

    import { Injectable } from '@angular/core';
    import { HttpHeaders,HttpClient } from '@angular/common/http';
    import { Router } from '@angular/router';
    import { Globals } from '../shared/api';

    import { Observable } from 'rxjs/Observable';
    private loginUrl = this.globals.LOGIN_URL;
    private loggedIn = false;
    public loading: boolean = false;


    constructor(private http: HttpClient, private globals: Globals) { }

    login(email: string, password: string):Observable<any> {
       const headers = new HttpHeaders({'Content-Type':'application/json;})

    return this.http.post(this.loginUrl, JSON.stringify({ email, password }), { headers });
}

Revised Component:
Put the logic inside susbscribe call back to ensure that spinner goes off only when your request is resolved.

   export class LoginComponent implements onInit {
      constructor(private router:Router){}
      public loading: boolean;

      //form ngSubmit function()
      login() {
        if (this.user.email, this.user.password) {
          this.loading = true;
          this.userSrv.login(this.user.email, this.user.password).subscribe(res 
                => {
            let data = res;

            if (data.token) {
                this.loading = false;
                window.location.href = '/';
            }
            else {
                this.loading = false;
                this.router.navigateByUrl('/login');
            }

        }, error => {
            this.loading = false;
        });
}}

revised HTML

<button type="submit" class="btn  btn-accent btn-block btn-flat b-r-10" (click)="login()" style="background: #FF473A;">
      Sign In
      <i class="fa fa-spinner fa-spin" *ngIf="loading"></i>
    </button>

Solution 2

First in your component.html

<button type="submit" class="btn  btn-accent btn-block btn-flat b-r-10" (click)="login()" style="background: #FF473A;">
      Sign In
      <i class="fa fa-spinner fa-spin" *ngIf="loading"></i>
    </button>

And now you could put this.loading=false; in subscriber like this:

export class LoginComponent implements onInit {
private loading: boolean;

 //form ngSubmit function()
 login() {
  if (this.user.email, this.user.password) {
      this.loading = true;
      this.userSrv.login(this.user.email, this.user.password)
      .subscribe((res: any) =>  {
               this.loader = false;
               //check your condition here and redirect to 
          },
           (error) => {
              this.loader = false;
        });
        }
     }
  }

In your service.ts file like:

login(email: string, password: string) {
    return this.http.post(this.loginUrl, JSON.stringify({
       email, password
    }));
};

Hope this will help you !

Share:
18,449

Related videos on Youtube

CE0
Author by

CE0

Updated on June 04, 2022

Comments

  • CE0
    CE0 about 2 years

    I am trying to create a spinner when button is clicked but it seems its not being run, this is what i did in my component.html

    <button type="submit" class="btn  btn-accent btn-block btn-flat b-r-10" style="background: #FF473A;">
      Sign In
      <i class="fa fa-spinner fa-spin" *ngIf="loading"></i>
    </button>
    

    and in component.ts

    export class LoginComponent implements onInit {
      private loading: boolean;
    
      //form ngSubmit function()
      login() {
        if (this.user.email, this.user.password) {
          this.loading = true;
          this.userSrv.login(this.user.email, this.user.password); //api call here
          this.loading = false;
        }
      }
    }
    

    okay my service.ts

    import { Injectable } from '@angular/core';
    import { Http, Headers, RequestOptions } from '@angular/http';
    import { Router } from '@angular/router';
    import { Globals } from '../shared/api';
    import 'rxjs/add/operator/toPromise';
    import { Observable } from 'rxjs/Observable';
    

    @Injectable() export class UserService {

    private loginUrl = this.globals.LOGIN_URL;
    private loggedIn = false;
    public loading: boolean = false;
    
    
    constructor(private http: Http, private router: Router, private globals: Globals) { }
    
    login(email: string, password: string) {
        let headers = new Headers();
        this.loading = true;
        headers.append('Content-Type', 'application/json');
        return this.http.post(this.loginUrl, JSON.stringify({ email, password }), { headers })
            .subscribe(res => {
                let data = res.json();
    
                if (data.token) {
                    this.loading = false;
                    window.location.href = '/';
                }
                else {
                    this.loading = false;
                    this.router.navigateByUrl('/login');
                }
    
            }, error => {
                this.loading = false;
            })
    };
    

    and this is what i hope to achieve when clicked

    enter image description here

    • CE0
      CE0 about 6 years
      @Vikas thanks for downvoting, let me update the question to display all what i have
  • CE0
    CE0 about 6 years
    using your code in service.ts still didn't work as expected login(email: string, password: string) { this.loading = true; return this.http.post(this.loginUrl, JSON.stringify({ email, password })) .subscribe(res => { this.loading = false; window.location.href = '/'; } else { this.loading = false; this.router.navigateByUrl('/login'); } }, error => { this.loading = false; }) }; @Sanoj_V
  • CE0
    CE0 about 6 years
    sorry for the wrong formatting, couldn't figure out how to format in comments
  • Sanoj_V
    Sanoj_V about 6 years
    Use this in your service.ts login(email: string, password: string) { return this.http.post(this.loginUrl, JSON.stringify({ email, password })); }; only.
  • CE0
    CE0 about 6 years
    error: property "subscribe" does not exist on type "void". the error comes up on the subscribe part. you should know that i'm using old Http and not HttpClient. think it matters here?
  • Sanoj_V
    Sanoj_V about 6 years
    use observable in service.ts=> login function login<T>(email: string, password: string): Observable<T>{ return this.http.post(this.loginUrl, JSON.stringify({ email, password })); } Observable need to import in service.ts
  • Sanoj_V
    Sanoj_V about 6 years
    import { Observable } from 'rxjs/Observable';
  • CE0
    CE0 about 6 years
    Thanks converting to HttpClientModule did it but now I have to change it for everywhere else I used HttpModule....nice one
  • Vikas
    Vikas about 6 years
    Glad I could help
  • CE0
    CE0 about 6 years
    Can we have a private? Have an error resulting from the change that i need help on...thanks bro...I don't know how to initiate chat though so if you can I will appreciate.
  • Vikas
    Vikas about 6 years
    you could update your question with the new error you getting
  • CE0
    CE0 about 6 years
    i will just make it a new question as they are unrelated really and i will past the link to the question here for you...okay?
  • CE0
    CE0 about 6 years
    okay nice so here is the link stackoverflow.com/questions/50307636/…
  • USQ91
    USQ91 over 4 years
    Beautiful and simple solution