Daniel Grima Daniel Grima - 29 days ago 9
AngularJS Question

Angular2 RxJS calling class function from map function

I'm new to Angular 2 and Observables so I apologise if my problem is trivial. Anyway I'm trying to test the Angular 2 HTTP Client using RxJS. Although I got it to work I need to add more logic to the service I'm currently working on. Basically I'd like to have a mapping function to convert the object I receive from the web service I'm connected to, to the model object I have in Angular.

This is the code that works:

import { Injectable } from 'angular2/core';
import { Http, Response } from 'angular2/http';
import { Observable } from 'rxjs/Observable';

import { Person } from '../models/person';

@Injectable()
export class PersonsService {

constructor(private http: Http) { }

private personsUrl = 'http://localhost/api/persons';

getPersons(): Observable<Person[]> {
return this.http.get(this.personsUrl)
.map(this.extractData)
.catch(this.handleError);
}

private extractData(res: Response) {
if(res.status < 200 || res.status >= 300) {
throw new Error('Bad response status ' + res.status);
}

let body = res.json();
return body.data || {};
}

private handleError(error: any) {
let errMsg = error.message;
return Observable.throw(errMsg);
}
}


With the above code I have no problems whatsoever. The issue I'm having is that I'd like to map the object I'm getting from the service to the one I have in Angular i.e.
Person
. What I tried is to call another function from the
extractData
function that's being used by the
.map
function.

private extractData(res: Response) {
if(res.status < 200 || res.status >= 300) {
throw new Error('Bad response status ' + res.status);
}

let body = res.json();
// map data function
var data = this.mapData(body.data);

return data || {};
}

private mapData(data: any) {
// code to map data
}


Obviously the code above doesn't work as when
this
is referenced inside the
extractData
function,
this
does not refer to the
PersonsService
class, but it refers to a
MapSubscriber
object.

I don't know if it is possible to call an "external" function. It might be a silly thing but I can't find any information regarding this.

Answer Source

Instead of just passing the function reference use arrow functions to retain this

.map((res) => this.extractData(res))