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.
Instead of just passing the function
reference use arrow
functions to retain this
.map((res) => this.extractData(res))
Observable's map function allows you to pass a reference variable as a second argument on how should this
actually work inside the higher-order function.
so the solution is.map(this.extractData,this)
This way while passing the extractData function you are also passing the current class's this
execution context to the higher-order function.
It will work.
Observable Doc Reference Link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With