page navigationend change angular angular2-services

navigationend - router events subscribe angular 4



Cómo extender la clase http 2 angular en Angular 2 final (6)

Creo que la respuesta de peeskillet debería ser la respuesta seleccionada, así que lo que estoy poniendo aquí solo pretende aumentar su respuesta en lugar de competir con ella, pero también quería dar un ejemplo concreto ya que no creo que sea 100% obvio exactamente a qué código se traduce la respuesta de peeskillet.

app.module.ts siguiente en la sección de providers de mi app.module.ts . Estoy llamando a mi reemplazo de Http personalizado MyHttp .

Observe cómo, como dijo peeskillet, sería provide: Http , no provide: MyHttp .

providers: [ AUTH_PROVIDERS { provide: Http, useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => { return new MyHttp(backend, defaultOptions); }, deps: [XHRBackend, RequestOptions] } ],

Entonces mi clase de extensión Http se define así:

import { Injectable } from ''@angular/core''; import { Http } from ''@angular/http''; @Injectable() export class MyHttp extends Http { get(url: string, options?: any) { // This is pointless but you get the idea console.log(''MyHttp''); return super.get(url, options); } }

No es necesario hacer nada especial para que su aplicación use MyHttp lugar de Http .

Estoy intentando ampliar la clase http de angular 2 para poder manejar errores globales y configurar encabezados para mi servicio secureHttp. Encontré algunas soluciones pero no funciona con la versión final de Angular 2. Aquí está mi código:

Archivo: secureHttp.service.ts

import { Injectable } from ''@angular/core''; import { Http, ConnectionBackend, Headers, RequestOptions, Response, RequestOptionsArgs} from ''@angular/http''; @Injectable() export class SecureHttpService extends Http { constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) { super(backend, defaultOptions); } }

Archivo: app.module.ts

import { BrowserModule, Title } from ''@angular/platform-browser''; import { NgModule } from ''@angular/core''; import { routing } from ''./app.routes''; import { AppComponent } from ''./app.component''; import { HttpModule, Http, XHRBackend, RequestOptions } from ''@angular/http''; import { CoreModule } from ''./core/core.module''; import {SecureHttpService} from ''./config/secure-http.service'' @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, CoreModule, routing, HttpModule, ], providers: [ { provide: Http, useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => { return new SecureHttpService(backend, defaultOptions); }, deps: [ XHRBackend, RequestOptions] }, Title, SecureHttpService], bootstrap: [AppComponent], }) export class AppModule { }

componente.ts

constructor(private titleService: Title, private _secure: SecureHttpService) {} ngOnInit() { this.titleService.setTitle(''Dashboard''); this._secure.get(''http://api.example.local'') .map(res => res.json()) .subscribe( data => console.log(data) , err => console.log(err), () => console.log(''Request Complete'') ); }

Por ahora me devuelve un error ''¡Ningún proveedor para ConnectionBackend!''. ¡Gracias por la ayuda!


Desde Angular 4.3, ya no necesitamos extends http . En su lugar, podemos usar HttpInterceptor y HttpClient para archivar todas estas cosas.

Es similar y más fácil que usar Http .

Emigré a HttpClient en aproximadamente 2 horas.

El detalle esta here


El motivo del error es porque está intentando proporcionar SecureHttpService

providers: [SecureHttpService]

Lo que esto significa es que Angular intentará crear la instancia, sin usar su fábrica. Y no tiene un proveedor registrado con el token ConnectionBackend para dar a su constructor.

Podría eliminar el SecureHttpService de los providers , pero eso le dará otro error (que supongo que es por lo que lo agregó en primer lugar). El error será algo así como "no hay proveedor para SecureHttpService" porque está intentando inyectarlo en su constructor

constructor(private titleService: Title, private _secure: SecureHttpService) {}

Aquí es donde necesitas entender sobre tokens. Lo que usted proporciona como el valor a provide es el token .

{ provide: Http, useFactory: () }

El token es lo que se nos permite inyectar. Por lo tanto, puede inyectar el Http y usará su SecureHttpService creado. Pero esto te quitará cualquier posibilidad que tengas de usar el Http regular, si alguna vez lo necesitas.

constructor(private titleService: Title, private _secure: Http) {}

Si no necesita saber nada sobre el SecureHttpService , entonces puede dejarlo así.

Si desea poder inyectar realmente el tipo SecureHttpService (tal vez necesite alguna API o quizás desee utilizar el Http normal en otro lugar), simplemente cambie la provide

{ provide: SecureHttpService, useFactory: () }

Ahora puede inyectar tanto el Http regular como su SecureHttpService . Y no olvide eliminar el SecureHttpService de los providers .


En realidad, solo puede extender el Http en su propia clase y luego usar una fábrica personalizada para proporcionar Http como eso:

luego, en mis Proveedores de aplicaciones pude usar una Fábrica personalizada para proporcionar ''Http''

importar {RequestOptions, Http, XHRBackend} desde ''@ angular / http'';

class HttpClient extends Http { /* insert your extended logic here. In my case I override request to always add my access token to the headers, then I just call the super */ request(req: string|Request, options?: RequestOptionsArgs): Observable<Response> { options = this._setCustomHeaders(options); // Note this does not take into account where req is a url string return super.request(new Request(mergeOptions(this._defaultOptions,options, req.method, req.url))) } } } function httpClientFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http { return new HttpClient(xhrBackend, requestOptions); } @NgModule({ imports:[ FormsModule, BrowserModule, ], declarations: APP_DECLARATIONS, bootstrap:[AppComponent], providers:[ { provide: Http, useFactory: httpClientFactory, deps: [XHRBackend, RequestOptions]} ], }) export class AppModule { constructor(){ } }

con este enfoque no necesita anular ninguna de las funciones Http que no desea cambiar


Puede consultar https://www.illucit.com/blog/2016/03/angular2-http-authentication-interceptor/ que le ayudará.

Cambie sus proveedores como se muestra a continuación para obtener el último lanzamiento y verifíquelo:

providers: [ { provide: SecureHttpService, useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => { return new SecureHttpService(backend, defaultOptions); }, deps: [ XHRBackend, RequestOptions] }, Title ]


Vea mi article sobre cómo extender la clase Http para Angular 2.1.1

Primero, vamos a crear nuestra clase de proveedor http personalizada.

http.service.ts import {Injectable} from ''@angular/core''; import {Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers} from ''@angular/http''; import {Observable} from ''rxjs/Observable''; import ''rxjs/add/operator/map''; import ''rxjs/add/operator/catch''; @Injectable() export class HttpService extends Http { constructor (backend: XHRBackend, options: RequestOptions) { let token = localStorage.getItem(''auth_token''); // your custom token getter function here options.headers.set(''Authorization'', `Bearer ${token}`); super(backend, options); } request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> { let token = localStorage.getItem(''auth_token''); if (typeof url === ''string'') { // meaning we have to add the token to the options, not in url if (!options) { // let''s make option object options = {headers: new Headers()}; } options.headers.set(''Authorization'', `Bearer ${token}`); } else { // we have to add the token to the url object url.headers.set(''Authorization'', `Bearer ${token}`); } return super.request(url, options).catch(this.catchAuthError(this)); } private catchAuthError (self: HttpService) { // we have to pass HttpService''s own instance here as `self` return (res: Response) => { console.log(res); if (res.status === 401 || res.status === 403) { // if not authenticated console.log(res); } return Observable.throw(res); }; } }

Ahora, necesitamos configurar nuestro módulo principal para proporcionar XHRBackend a nuestra clase http personalizada. En su declaración del módulo principal, agregue lo siguiente a la matriz de proveedores:

app.module.ts

import { HttpModule, RequestOptions, XHRBackend } from ''@angular/http''; import { HttpService } from ''./services/http.service''; ... @NgModule({ imports: [..], providers: [ { provide: HttpService, useFactory: (backend: XHRBackend, options: RequestOptions) => { return new HttpService(backend, options); }, deps: [XHRBackend, RequestOptions] } ], bootstrap: [ AppComponent ] })

Después de eso, ahora puede usar su proveedor http personalizado en sus servicios. Por ejemplo:

user.service.ts

import { Injectable } from ''@angular/core''; import {HttpService} from ''./http.service''; @Injectable() class UserService { constructor (private http: HttpService) {} // token will added automatically to get request header getUser (id: number) { return this.http.get(`/users/${id}`).map((res) => { return res.json(); } ); } }