I would appreciate if someone could shed some light on this. I have been at it for days now.
Here is two functions that lives in my auth service. The login function that retrieves a valid jwt and then the refresh function that fetches a refreshed jwt.
LOGIN
login(username: string, password: string): Observable<any> {
const headers = new HttpHeaders().set('Authorization', `Basic ${environment.WSO2_AUTH_BASIC}`);
const params = new HttpParams({
fromObject: {
grant_type: 'password',
scope: 'openid',
username: username,
password: password
}
});
return this.http.request<Token>('POST', environment.API_HOST + '/token', {
headers: headers,
body: params
}).pipe(map(this._mapTokenResponse));
}
REFRESH
private _refreshToken() {
const headers = new HttpHeaders().set('Authorization', `Basic ${environment.WSO2_AUTH_BASIC}`);
this.token = this.getToken();
const params = new HttpParams({
fromObject: {
grant_type: 'refresh_token',
scope: 'openid',
refresh_token: this.token.refresh_token
}
});
return this.http.request<Token>('POST', environment.API_HOST + '/token', {
headers: headers,
params: params
}).pipe(map(this._mapTokenResponse, this));
}
I have created a separate arrow function that handles the mapping for both.
private _mapTokenResponse = (token: Token) => {
// login successful if there's a jwt token in the response
if (token && token.access_token) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
token.id_token_data = this.jwtHelper.decodeToken(token.id_token);
this._setSession(token);
}
return token;
}
I want this so that I do not duplicate code. The login function works perfectly but the refresh token returns this error:
ERROR Error: "Uncaught (in promise): TypeError: argument is not a function. Are you looking for `mapTo()`?
I have imported map from 'rxjs/operators'
Either you can do:
return this.http.request<Token>('POST', environment.API_HOST + '/token', {
headers: headers,
body: params
}).pipe(
map(this._mapTokenResponse.bind(this))
);
We use .bind(this)
to set up the scope (the "this") of the function call. Otherwhise, you'll get an error each time you call this.
in your callback function.
Or:
return this.http.request<Token>('POST', environment.API_HOST + '/token', {
headers: headers,
body: params
}).pipe(
map((token: Token) => this._mapTokenResponse(token))
);
This solution is much cleaner in my opinion.