Angular 2's Http service not exposing map() an

2019-01-11 04:38发布

Does anybody know if there's been any breaking changes to the http between alpha 45 and alpha 48? I've been searching around and I didn't find anything. My problem is that the code below was working perfectly on Alpha 45. But now that I've upgraded to Alpha 48 I am getting a _this.http.post(...).map is not a function error message when I try to run the application. The strange thing is that IntelliSense shows that http.post is returning an observable. Which means that the map function should be available. Any help would be appreciated. Thanks!

public Authenticate(username: string, password: string): Observable<boolean> {

    this.ResetAuthenticationValues();

    return Observable.create((subscriber: EventEmitter<string>) => { 

        let body: string = 'grant_type=password&username=' + username + '&password=' + password;
        let headers = new Headers();
        headers.append('Content-Type', 'application/x-www-form-urlencoded');

        this.http.post('http://example.com', body, {headers: headers})
            .map(res => res.json())
            .subscribe(
                (data: DataResponse) => {
                    if (!data.error) {
                        this.accessToken = {access_token: data.access_token, token_type: data.token_type};
                        subscriber.next(this.isAuthenticated = true);                       
                    }
                    else
                        subscriber.error(this.isAuthenticated = false);
                },
                (err) => subscriber.error(err),
                () => subscriber.complete()
            );

        return () => { };
    });
} 

5条回答
Fickle 薄情
2楼-- · 2019-01-11 05:00

You need to import the Rx map operator in your component like

import 'rxjs/add/operator/map';

Cheers!

查看更多
祖国的老花朵
3楼-- · 2019-01-11 05:08

Another update (cough, sorry about that, forgot this option)

If you want to avoid adding individually the operators you can import the full Rx by doing

import {Observable, Subject, ReplaySubject, etc...} from 'rxjs/Rx';

You'll have all the operators :)

Update alpha 50 (08/12/2015)

Shortly after alpha 49 was released, they released alpha 50. This version upgraded rxjs to alpha 14. So you'll good to go by doing

npm install angular2@latest
npm install rxjs@5.0.0-alpha.14

Update alpha 49 (08/12/2015)

As of now alpha 49 was released and this didn't change, which means this will remain in time. The original answer is still valid with a few changes, paths changed for rjxs, so it should be as follows :

System.config({
    paths: {
        'rxjs/add/observable/*' : 'node_modules/rxjs/add/observable/*.js',
        'rxjs/add/operator/*' : 'node_modules/rxjs/add/operator/*.js',
        'rxjs/*' : 'node_modules/rxjs/*.js'
    }
});

import 'rxjs/add/operator/map';

Note

This version requires exactly the alpha 13 version, so if in your package.json you have already another version, you'll have to remove it, install angular2, and then install rjxs.

Update

The CHANGELOG was updated to show this breaking change. There's a comment from @jeffbcross in issue #5642 that clarifies a LOT in this matter.

Quoting part of that comment

Modularity was a goal of the new RxJS project from the start, and it wasn't until recently that we started really getting serious about composing operators instead of relying on tiered distributions of Rx.

Original answer

There was actually a breaking change regarding RxJS and Angular2. So now to use operators like map you have to import them separately. You can see the change in this pull request. And there's already an issue about your question.

I recommend you to stick to alpha 47. But to everyone who needs and want to know what the solution is, like in the pull request is specified, to add the operator separately.

You must have something like this

import {Http, ...} ...;

// Component
constructor(http: Http) {
    http.get(...).map() // 'map' doesn't exist! Ouch!
}

To fix it, add the operator (sorry for repeating it so many times) and configure the paths to rxjs

Note

This must be done with RxJS alpha 11, or alpha 12 (don't confuse it with @reactivex/rxjs, now it's just rxjs). So install it with

npm install rxjs@5.0.0-alpha.11

Or just npm install rxjs if you want the latest, although they lock it to be alpha 11.

Configure the paths in your System.config (note that this is my config, not necessarily the best and I'm assuming you installed alpha 11)

System.config({
    paths: {
        'rxjs/observable/*' : 'node_modules/rxjs/observable/*.js',
        'rxjs/operators/*' : 'node_modules/rxjs/operators/*.js',
        'rxjs/*' : 'node_modules/rxjs/*.js'
    }
});

After you are done with the configuration, you can import the operator as follows

 import 'rxjs/operators/map';

And that's all. You'll have to do that with every operator. So I repeat, I recommend you to stick to alpha 47, like I told you in the comment. I will try to update the answer later with a plnkr.

查看更多
时光不老,我们不散
4楼-- · 2019-01-11 05:16

In contrast to what what's written above, I found that I needed to use

    System.config({
        packages: {
            'app': {defaultExtension: 'js'},
            'node_modules': {defaultExtension: 'js'}
        },
        paths: {
            'rxjs/*' : 'node_modules/rxjs/*.js'
        }
    });

The node_modules defaultExtension was the critical think for me (I dunno why the rxjs/* path doesn't add the .js but hey ho.)

This works from 48 to the latest 52.

查看更多
不美不萌又怎样
5楼-- · 2019-01-11 05:17

I had this issue and it turned out to be an issue with the version of rxjs - angular 2.0.0-rc4 requires rxjs-5.0.0-beta.6, I had beta.10 in my jspm config!

查看更多
走好不送
6楼-- · 2019-01-11 05:19

If you want to use the Beta versions of Angular 2 or the future real production releases, then you need to do two things to get this to work.

1) You'll first need to update your System.config() configuration in index.html to include references to RxJS:

System.config({
    map: {
        'rxjs': 'node_modules/rxjs'
    },
    packages: {
        'app': {defaultExtension: 'js'}, // assumes your code sites in `src/app`
        'rxjs': {defaultExtension: 'js'}
    }
});
System.import('app/app'); // this assumes your main file is `app.ts` and it sits in the `app` folder.

2) Then you can import map() and other (or all) RxJS operators into your application with import lines in your main file (app.ts in my case):

import 'rxjs/Rx'; // this would import all RxJS operators

If you rather import just map() to keep the size down, you would do this instead:

import 'rxjs/add/operator/map';

You do not need to import these into each class file. Just import them into your main file to make them accessible to all your other components/services/directives.

查看更多
登录 后发表回答