Add Http manually in Angular 4

I want to manually download an Angular 4 application (created using the CLI). In main.ts I do this:

 const injector = ReflectiveInjector.resolveAndCreate([ Http, BrowserXhr, {provide: RequestOptions, useClass: BaseRequestOptions}, {provide: ResponseOptions, useClass: BaseResponseOptions}, {provide: ConnectionBackend, useClass: XHRBackend}, {provide: XSRFStrategy, useFactory: () => new CookieXSRFStrategy()}, ]); const http = injector.get(Http); http.get('assets/configs/configuration.json') .map((res: Response) => { return res.json(); }).subscribe((config: Configuration) => { configuration = config; console.log(JSON.stringify(configuration)); platformBrowserDynamic().bootstrapModule(AppModule); }); 

It seems I am getting a valid instance of Http, but when I use it ( http.get ) I get this error:

 Uncaught TypeError: Cannot read property 'getCookie' of null at CookieXSRFStrategy.webpackJsonp.../../../http/@angular/http.es5.js.CookieXSRFStrategy.configureRequest (vendor.bundle.js:141626) 

My http object looks like this: enter image description here

+1
source share
4 answers

You can use the HttpClient service before Angular starts using the ReflectiveInjector as follows:

 import { ReflectiveInjector } from '@angular/core'; import { HttpClient, HttpClientModule } from '@angular/common/http'; const injector = ReflectiveInjector.resolveAndCreate(getAnnotations(HttpClientModule)[0].providers); const http = injector.get(HttpClient); http.get('/posts/1').subscribe((r) => { ConfigurationService.configuration = <Configuration>JSON.parse(config); platformBrowserDynamic().bootstrapModule(AppModule); }); 

This line:

 getAnnotations(HttpClientModule).providers 

refers to all providers registered in the HttpClientModule , so you do not need to specify them manually. This answer details the getAnnotations function.

The approach I showed is โ€œkind ofโ€ similar to what you do when importing an HttpClientModule into an AppModule :

 @NgModule({ imports: [HttpClientModule, ...], }) export class AppModule {} 

See this plunger for more details.

+4
source

As another approach, you can use your own browser to extract the api . This way you don't have to deal with angular http, etc.

Here is how I do it:

 fetch(configUrl, { method: 'get' }) .then((response) => { response.json() .then((data: any) => { if (environment.production) { enableProdMode(); }; platformBrowserDynamic([{ provide: AppSettings, useValue: new AppSettings(data.config) }]).bootstrapModule(AppModule); }); }); 

But donโ€™t forget that fetch didnโ€™t get much love in old browsers , so you need to polish to whatwg-fetch , for example npm install whatwg-fetch --save , then import 'whatwg-fetch' in polyfills.ts if you want to support old browsers.

UPDATE: Yes, you can use XMLHttpRequest , but you get the same browser support as fetch, just a new replacement for XMLHttpRequest .

+3
source

Thank you, Kuntsevich. I came up with this solution that works great:

 function httpGetAsync(theUrl, callback) { const xmlHttp = new XMLHttpRequest(); xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { callback(xmlHttp.responseText); } } xmlHttp.open('GET', theUrl, true); // true for asynchronous xmlHttp.send(null); } httpGetAsync('assets/configs/configuration.json', (config: string) => { ConfigurationService.configuration = <Configuration>JSON.parse(config); platformBrowserDynamic().bootstrapModule(AppModule); }); 
+1
source

Perhaps the original answer worked earlier, but in Angular 5 I could not use it, there was no definition for the getAnnotations function. This is what worked for me, however:

 import { ReflectiveInjector } from '@angular/core'; import { HttpClient, XhrFactory, HttpHandler, HttpXhrBackend, HttpBackend } from '@angular/common/http'; // https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts#L45 export class BrowserXhr implements XhrFactory { build(): any { return <any>(new XMLHttpRequest()); } } const injector = ReflectiveInjector.resolveAndCreate([ HttpClient, HttpXhrBackend, { provide: HttpBackend, useExisting: HttpXhrBackend }, { provide: HttpHandler, useExisting: HttpBackend }, { provide: XhrFactory, useClass: BrowserXhr}, ]); const http: HttpClient = injector.get(HttpClient); http.get('/url').subscribe((response) => { console.log(response); }); 
0
source

Source: https://habr.com/ru/post/1260183/


All Articles