xerotolerant
xerotolerant

Reputation: 2079

RXJS Angular 2 observable losing track if 'this'

Hello I have an anuglar 2 application and I am having trouble using observable for http requests. It works fine in general. I am just wondering, why does it seem to lose track of 'this'?

loginWithEmailAndPassword(email: string, password: string){
    let headers = new Headers({ 'Content-Type': 'application/json'});
    let options = new RequestOptions({ headers: headers});
    return this.http.post('auth/login', {email: email, password: password}, options)
                    .map(this.extractData)
                    .catch(this.handleError)
}
private extractData(res: Response) {
    let body = res.json();
    // console.log(body);
    if (body.token){
         this.saveToken(body.token);
         localStorage.setItem('token', body.token);
    }

    return body || {}
}
private saveToken(token: string){ 
    localStorage.setItem('token', token);
}

In the block

 if (body.token){
         this.saveToken(body.token);
         localStorage.setItem('token', body.token);
    }

I get the error

user.service.ts:54 TypeError: this.saveToken is not a function
at MapSubscriber.webpackJsonp.../../../../../src/app/user/user.service.ts.UserService.extractData [as project] (user.service.ts:31)
at MapSubscriber.webpackJsonp.../../../../rxjs/operator/map.js.MapSubscriber._next (map.js:77)
at MapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at XMLHttpRequest.onLoad (http.es5.js:1226)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Object.onInvokeTask (core.es5.js:3881)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:191)
at XMLHttpRequest.ZoneTask.invoke (zone.js:486)

What is the proper way to refer to other methods in a class using this pattern. I highly doubt we're supposed to go back to var self = this

Upvotes: 0

Views: 300

Answers (1)

borislemke
borislemke

Reputation: 9136

Change this line

.map(this.extractData)

to

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

This is because the scoping of the above lines are different. The this inside the first (your original code) will point to the function itself, while the second, using the fat arrow function, will ensure that the this refers to the outer scope of the function.

Upvotes: 2

Related Questions