Angular injecting toastr service

2k Views Asked by At

I want to handle common http errors using angular materials mdsnackbar service, however, i cannot figure out how to implement it. It gives me an error such as do not match any parameter type if i add to MdSnackBar to constructor like private mdsnackbar: MdSnackBarcause the class itself using super

I would like to know if there is an another way to achive the same result.

http-interceptor

import { Injectable } from '@angular/core';
import {
  ConnectionBackend,
  RequestOptions,
  Request,
  RequestOptionsArgs,
  Response,
  Http,
  Headers,
} from '@angular/http';

import { ToastrService } from './toastr.service'
import { MdSnackBar } from '@angular/material';

import { Observable } from 'rxjs/Rx';
import { environment } from '../environments/environment';


@Injectable()

export class HttpInterceptorService extends Http {
  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
    super(backend, defaultOptions);
  }



  request(
    url: string | Request,
    options?: RequestOptionsArgs
  ): Observable<Response> {
    return super.request(url, options).catch(this.catchErrors());
  }

  catchErrors() {
    return (res: Response) => {
      console.log(res);
      if (res.status === 401) {
         // this.toastrService.showToaster('Hello World');
         return Observable.throw(res);
      }
      return Observable.throw(res);
    };
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    url = this.updateUrl(url);
    console.log(url);
    return super.get(url, this.getRequestOptionArgs(options));
  }

  post(
    url: string,
    body: string,
    options?: RequestOptionsArgs
  ): Observable<Response> {
    url = this.updateUrl(url);
    return super.post(url, body, this.getRequestOptionArgs(options));
  }

  put(
    url: string,
    body: string,
    options?: RequestOptionsArgs
  ): Observable<Response> {
    url = this.updateUrl(url);
    return super.put(url, body, this.getRequestOptionArgs(options));
  }

  delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    url = this.updateUrl(url);
    return super.delete(url, this.getRequestOptionArgs(options));
  }

  private updateUrl(req: string) {
    return environment.origin + req;
  }

  private getRequestOptionArgs(
    options?: RequestOptionsArgs
  ): RequestOptionsArgs {
    if (options == null) {
      options = new RequestOptions();
    }
    if (options.headers == null) {
      options.headers = new Headers();
    }
    options.headers.append('Content-Type', 'application/json');
    return options;
  }
}

toastrservice

 import { Injectable } from '@angular/core';
 import { MdSnackBar } from '@angular/material';

@Injectable()
export class ToastrService {

  constructor(private snackBar: MdSnackBar) {
  }

  showToaster(msg: string) {
      this.snackBar.open(msg, null, {
          duration: 3000,
      });
  }

}

http.service.ts

import { XHRBackend, Http, RequestOptions } from '@angular/http';
import { HttpInterceptorService } from './shared/http-interceptor.service';
import { ToastrService } from './shared/toastr.service'

export function httpService(
  xhrBackend: XHRBackend,
  requestOptions: RequestOptions,
  toastr: ToastrService // forget to insert it
): Http {

  return new HttpInterceptorService(xhrBackend, requestOptions, toastr);
}

app.module.ts

providers: [
    DataserviceService,
    HttpInterceptorService,
    ToastrService,
    {
      provide: Http,
      useFactory: httpService,
      deps: [XHRBackend, RequestOptions, ToastrService],
    },

I have update dependencies on both http.service.ts and app.module.ts and it worked like a charmm.

1

There are 1 best solutions below

1
On BEST ANSWER

You need to add it to the constructor parameter list

@Injectable()

export class HttpInterceptorService extends Http {
  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private toastr:ToastrService) {
    super(backend, defaultOptions);
  }

You also need to provide ToastrService somewhere so it can be injected.

@NgModule({
  ...,
  providers: [ToastrService], 
}}

MdSnackBar also needs to be provided somewhere, for example by importing the module that provides it.