Nikita Marinosian
Nikita Marinosian

Reputation: 797

Angular 2 API service to display error UI message

I'm new to Angular 2, so excuse me if the question is silly.

I have to fetch data from the server and display it in the component. The server has some API methods, so I've created the api.service.ts which looks like this:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

const protocol = 'http';
const domain = 'mydomain.ng';
const port = ':4200';

@Injectable()
export class ApiService {

  constructor(private http: HttpClient) { }

  buildQuery(apiMethod: string) {
    return `${protocol}://${domain}${port}/${apiMethod}`;
  }

  get(apiMethod: string): Observable<Response> {

    const query = this.buildQuery(apiMethod);

    return this.http.get<Response>(query)
    .map(
      resp => {
        if (resp.ok) {
          return resp;
        } else { // Server returned an error
          // here I need to show UI error in the component
        }
      }
    )
    .catch( // Error is on the client side
      err => {
        // here I need to show UI error in the component
      }
    );
  }

  getGeneralReport(): Observable<Response> {
    return this.get('generalReport');
  }
}

Server API has a lot of methods, so the get() method is designed to perform the actual request and handle common mistakes. Then I will have methods like getGeneralReport() which will call the get method with the parameter specifying which API method should be used.

Also I have a component called general.component.ts where the api.service is injected:

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../shared/api/api.service';

@Component({
  selector: 'app-general',
  templateUrl: './general.component.html',
  styleUrls: ['./general.component.scss']
})
export class GeneralComponent implements OnInit {

  generalInfo: Response;

  constructor(private apiService: ApiService) { }

  ngOnInit() {
    this.apiService.getGeneralReport().subscribe(
      data => {
        this.generalInfo = data;
        // Display the received data
      }
    );
  }

}

There will be more components like general.component which will use the api.service. Now I'm stuck because I need to pop up the UI window in all the components which use api.service if the error occurs in api.service. Is it possible or should I use some different approach?

Upvotes: 1

Views: 2531

Answers (1)

komron
komron

Reputation: 2277

Yes it is possible, do it like this:

this.apiService.getGeneralReport().subscribe(
  data => {
    this.generalInfo = data;
    // Display the received data
  }, 
   err => {
      // yourPopupmethod(err)
   }
);

and in service throw error. So update your service by adding HandleError method:

handleError(error: Response | any) {
     return Observable.throw(new Error(error.status))
}

  get(apiMethod: string): Observable<Response> {

    const query = this.buildQuery(apiMethod);

    return this.http.get<Response>(query)
       .map(
           resp => {
              if (resp.ok) {
                 return resp;
              } else { // Server returned an error
                 this.handleError(resp);
                }
           }
         )
       .catch(
          err => {
             this.handleError(err);
          }
      );
    }

Upvotes: 2

Related Questions