Search code examples
angularangular-httpclient

How to process angular 4 HttpClient's response in the service and notify component


I was wondering, how can I easily notify a component about the http response (success or error) by using the new HttpClient (angular 4.3+ from @angular/common/http) after the response was processed (token saved) by the service.

Earlier, I was using this code (using @angular/http):

login(username: string, password: string): Observable<any> {    
  let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
  let options = new RequestOptions({ headers: headers });

  let url = this.apiAddr + '/login';
  var body = 'username=' + username + '&password=' + password;

  return this.http.post(url, body, options).map((res) => {
    let body = res.json();

    this.jwtoken = body.token;
    this.username = username;
    this.saveToken();                           
    return "Login successful!";
  })
  .catch(this.handleError);
 }

By using the new module, I'm not sure how to return the Observable and at the same time access it from the service. This is what I have at the moment (auth.service.ts):

login(username: string, password: string) {
  const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
  const url = apiAddr + '/login';
  const body = 'username=' + username + '&password=' + password;
  const options = {
    headers: headers,
  };


  this.http.post<LoginResponse>(url, body, options).subscribe(
    data => {
      this.jwtoken = data.token;
      this.username = username;
      this.lastTokenRefreshAt = new Date();
      this.saveUserToken();
    }, err => {
      console.log('Error occured');
      console.log(err);
    });
}

Now after that, I would like to notify the LoginComponent, where I could navigate to a different page.


Solution

  • Use the do operator of observable to access the response from the service when a component invokes it like this:

    import 'rxjs/add/operator/do';
    
    login(username: string, password: string) {
      const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
      const url = apiAddr + '/login';
      const body = 'username=' + username + '&password=' + password;
      const options = {
        headers: headers,
      };
    
      return this.http.post<LoginResponse>(url, body, options).do(
        data => {
          this.jwtoken = data.token;
          this.username = username;
          this.lastTokenRefreshAt = new Date();
          this.saveUserToken();
      });
    }
    

    you can catch the error in the component that calls login.