4

I need to get an instance of Http without using Angular2's DI ( constructor(private http: Http) )

The following code was taken from another stackoverflow question, and it works in Angular2 RC.4 and earlier versions, but not in RC.5+(HTTP_PROVIDERS is no longer available) :

const injector = ReflectiveInjector.resolveAndCreate([
  HTTP_PROVIDERS
]);

this.http = injector.get(Http);

There are several questions here on Stackoverflow with different variants of that same code, but none of them works in RC.5+.

Does anybody know of how to perform that same thing in RC.5+?

4
  • What if I show you how to use http in RC5 with DI? would it be fine? Commented Sep 21, 2016 at 17:29
  • I already know how to use Http with DI. Commented Sep 21, 2016 at 17:30
  • But as HTTP_PROVIDERS is removed, you can't use this way anymore. Commented Sep 21, 2016 at 17:31
  • I am aware of that. That is the very reason why I'm asking this. I even specified it in the question. Commented Sep 21, 2016 at 17:31

2 Answers 2

3

Just look at the source for HttpModule. You'll see all the providers required to create the Http. Most of those providers were what were in the now removed HTTP_PROVIDERS

export function _createDefaultCookieXSRFStrategy() {
  return new CookieXSRFStrategy();
}

export function httpFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http {
  return new Http(xhrBackend, requestOptions);
}

@NgModule({
  providers: [
    {provide: Http, useFactory: httpFactory, deps: [XHRBackend, RequestOptions]},
    BrowserXhr,
    {provide: RequestOptions, useClass: BaseRequestOptions},
    {provide: ResponseOptions, useClass: BaseResponseOptions},
    XHRBackend,
    {provide: XSRFStrategy, useFactory: _createDefaultCookieXSRFStrategy},
  ],
})
export class HttpModule {
}

Just add everything in the above providers to the array you pass to ReflectiveInjector.resolveAndCreate.

If your goal is to get the Http before bootstrap, there's another little thing you need to take care of, which is the CookieXSRFStrategy. It will not work prior to bootstrapping, as it is dependendent on some platform browser stuff. You can just replace it with a noop, as mentioned in this post

Sign up to request clarification or add additional context in comments.

2 Comments

This seems to be working (I won't be fully able to test it, since I also need to refactor other things in the app, but at least the app no longer crashes in the browser). I am a bit worried that I will only be able to make GET calls (since that's the default method with BaseRequestOptions), but I'll deal with that later. As soon as I test it, I will mark your answer as the valid one. I will also take a look at the source code more often, Thank you for letting me know how you came up with this answer.
I can't believe it. It works! Thank you very much for this answer.
0

Finally found an answer.

You can use Injector to get dependency as shown below.

service.ts

import { Injectable,Injector } from '@angular/core';
import {Http} from '@angular/http';

@Injectable()
export class Service{
    constructor(private injector:Injector){}

    display(){

        this.http=this.injector.get(Http);   //<<<<------here the magic happens

        console.log(this.http);
        return this.http.get('user.json').map(res => {return res.json()}).toPromise();
    } 
}


If you still have any doubt, you can check this working plunker made in Angular2.0.0 :
https://plnkr.co/edit/eWLB2BaL66pnJ7SC6qAL?p=preview

1 Comment

If injectable was available then one would use http at the constructor directly...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.