angular: http.get(..).map function is not working with alpha 48

since I updated to alpha 48, http.get(…).map is no longer working.

EXCEPTION: TypeError: json.map is not a function in [null]

@Injectable()
export class WPService implements IWPService {
    baseURL: string = 'http://localhost/wptest/api';
    http: Http;
    constructor(http: Http) {
        this.http = http;
    }
    GetPosts() {
        var query = this.baseURL + '/get_posts/';
        return new JsonObject(this.http.get(query));
    }
}

@Injectable()
export class JsonObject {
    constructor(json: Observable<any>) {
        json.map(res => res.json()).map(data => {          // <= 
            for (var entry in data) {
                if (data.hasOwnProperty(entry)) {
                    this[entry] = data[entry];
                }
            }
        }).subscribe();
    }
}

when I downgraded to alpha 47, .map worked again. maybe it has something to do with the integrated rxjs

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 4
  • Comments: 29 (8 by maintainers)

Commits related to this issue

Most upvoted comments

@aaronksaunders yep, this is “works as intended” - we are purposefully not shipping the 95+ operators that come with RxJS (and the associated 300KB or so they add) in favor of allowing opt-in to specific ones you want.

Longer term we may include a few with the http module by default, but for the moment its opt-in till we decide which ones are necessary. Ideally i’d like to obviate the need for .map entirely for 99% of use cases.

Easiest thing is in your main.ts (or whatever) file to either import them ad-hoc:

import 'rxjs/add/operator/map'

Or if you really don’t want to mess with it and want the whole kitchen sink o’ operators / specific Observables (eg Observable.fromEvent)

import 'rxjs/Rx' 

which will add all of them. Note that you only need to do the above once, before you use Http, not in every single file you are going to use it.

IMO This really needs to be added to the angular2 documentation (import rxjs/Rx or importing operators 1 by 1). I struggled for a day pulling my hair out not understand what I was missing about Observables and really thinking I was missing something massive (which I guess I was). It’s a difficult thing to just ‘know’ if you are new to angular2/Rxjs.

Am I the only person who cannot fathom why the http/jsonp examples on the Angular 2 site (Developer Guide - http client) – both in the sample code and the versions in the provided Plunker demos – fail to make this critical point? The .map and other operators used in these basic training examples do not reflect the required operator imports, and this is very counterproductive for those trying to learn Ang 2. (How the Plunker demos run these operators without the imports is still a mystery to me.) People trying to wrap their heads around Observables as a replacement for Promises – a worthwhile effort surely in the longer run – deserve not to be confused by the text and code in the official Angular 2 Developer Guide.

Guys, you have to add map (install rxjs@5.0.0-alpha.11)

import 'rxjs/operators/map';

I don’t know if for Http module we will always have to do this. As far as I know map is one of the defaults one. Anyway, with this you can make it work for now until you get an official answer

Note that I had to map it like this

System.config({
    paths: {
        // alpha 11
        'rxjs/operators/*' : 'node_modules/rxjs/operators/*.js'
        // alpha 12, 13 & 14
        'rxjs/add/operator/*' : 'node_modules/rxjs/add/operator/*.js'
        }
}

What’s the difference between the following?

import 'rxjs/add/operator/map'

and

import 'rxjs/operator/map'

I don’t get this bit about adding to your System.config() in the html page.

The problem is just that .map (and all of the operators for observables) need to be imported into the file in which you are using http or jspon.

Thus if you have a file for a service or component that calls http, and which you need .map() to handle the res.json () unwrap step (to grab the body from the response object), you need the following imports at the top of the file:

import {Http, Response} from ‘angular2/http’; import {Headers, RequestOptions} from ‘angular2/http’; (plus) import ‘rxjs/add/operator/map’; // to import just map operator (or) import ‘rxjs/Rx’; // if you want to import all the operators while developing and then go back and just import exactly what you ended up needing for production

It’s just that simple and it only because the observable(containing the repsonse object) returned by http method does not inherently have access to any operators – like map, do, etc, unless you provide them.

Your System.config need not refer to rxjs at all. The following works for me where all the my angular files (components, services, directives, etc.) are in an “app” folder.

  System.config({
    packages: {        
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    }
  });

But the rx bundle must be included with the other necessary script loads in the head of the html page.

<script src="node_modules/rxjs/bundles/Rx.js"></script>  

BTW: If all else fails, you can skip the map() call and subscribe directly to the response observable returned by the http call, like this:

    this.http.get('people')
       .subscribe(
            res => this.persons = res.json(),
            error =>  console.log(error)
            );

This at least proves that you are getting back an observable with the correct data. subscribe is not considered an operator, but rather a method of any observable instance. Thus it can never be missing.

We do call this out in the http doc, in its own Enable RxJS Operators section.

I don’t know how we can be more clear. Open to suggestions.

Much else has changed since this issue was raised. I suggest that we close this issue.

Chrome is throwing a 403 when doing what is described above, is anyone else seeing this?

node_modules/rxjs/Observable/ 403 (Forbidden)

I was upgrading from 2.0.0-alpha.44 to 2.0.0-beta.0, got the same issue and issue is fixed by adding a single line in app.ts

import 'rxjs/add/operator/map';

Thanks @robwormald

should be import 'rxjs/add/operator/map' - note the add in the import path. that brings in the self patching module.