如何处理angular 4 HttpClient在服务中的响应并通知组件
How to process angular 4 HttpClient's response in the service and notify component
我想知道,如何在响应完成后使用新的 HttpClient(来自@angular/common/http 的angular 4.3+)轻松通知组件有关 http 响应(成功或错误)由服务处理(保存令牌)。
早些时候,我使用了这段代码(使用@angular/http):
login(username: string, password: string): Observable<any> {
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
let url = this.apiAddr + '/login';
var body = 'username=' + username + '&password=' + password;
return this.http.post(url, body, options).map((res) => {
let body = res.json();
this.jwtoken = body.token;
this.username = username;
this.saveToken();
return "Login successful!";
})
.catch(this.handleError);
}
通过使用新模块,我不确定如何 return Observable 并同时从服务访问它。这是我目前拥有的 (auth.service.ts):
login(username: string, password: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const url = apiAddr + '/login';
const body = 'username=' + username + '&password=' + password;
const options = {
headers: headers,
};
this.http.post<LoginResponse>(url, body, options).subscribe(
data => {
this.jwtoken = data.token;
this.username = username;
this.lastTokenRefreshAt = new Date();
this.saveUserToken();
}, err => {
console.log('Error occured');
console.log(err);
});
}
之后,我想通知 LoginComponent,在那里我可以导航到不同的页面。
当组件像这样调用它时,使用 observable 的 do 运算符访问来自服务的响应:
import 'rxjs/add/operator/do';
login(username: string, password: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const url = apiAddr + '/login';
const body = 'username=' + username + '&password=' + password;
const options = {
headers: headers,
};
return this.http.post<LoginResponse>(url, body, options).do(
data => {
this.jwtoken = data.token;
this.username = username;
this.lastTokenRefreshAt = new Date();
this.saveUserToken();
});
}
您可以在调用登录的组件中捕获错误。
更新到 angular6 并使用新版本的 RxJs 后,我不得不更改 do 方法,因为它是 renamed/deprecated。为了获得与 Sonicd300 的答案类似的结果,我必须使用带管道的 tap 方法:
import { tap } from 'rxjs/operators';
login(username: string, password: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const url = this.apiAddr + '/login';
const body = 'username=' + username + '&password=' + password;
const options = {
headers: headers,
};
return this.http.post<LoginResponse>(url, body, options).pipe(
tap(
data => {
this.jwtoken = data.token;
this.username = username;
this.lastTokenRefreshAt = new Date();
this.saveUserToken();
return 'Login successful';
})
);
}
我想知道,如何在响应完成后使用新的 HttpClient(来自@angular/common/http 的angular 4.3+)轻松通知组件有关 http 响应(成功或错误)由服务处理(保存令牌)。
早些时候,我使用了这段代码(使用@angular/http):
login(username: string, password: string): Observable<any> {
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
let url = this.apiAddr + '/login';
var body = 'username=' + username + '&password=' + password;
return this.http.post(url, body, options).map((res) => {
let body = res.json();
this.jwtoken = body.token;
this.username = username;
this.saveToken();
return "Login successful!";
})
.catch(this.handleError);
}
通过使用新模块,我不确定如何 return Observable 并同时从服务访问它。这是我目前拥有的 (auth.service.ts):
login(username: string, password: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const url = apiAddr + '/login';
const body = 'username=' + username + '&password=' + password;
const options = {
headers: headers,
};
this.http.post<LoginResponse>(url, body, options).subscribe(
data => {
this.jwtoken = data.token;
this.username = username;
this.lastTokenRefreshAt = new Date();
this.saveUserToken();
}, err => {
console.log('Error occured');
console.log(err);
});
}
之后,我想通知 LoginComponent,在那里我可以导航到不同的页面。
当组件像这样调用它时,使用 observable 的 do 运算符访问来自服务的响应:
import 'rxjs/add/operator/do';
login(username: string, password: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const url = apiAddr + '/login';
const body = 'username=' + username + '&password=' + password;
const options = {
headers: headers,
};
return this.http.post<LoginResponse>(url, body, options).do(
data => {
this.jwtoken = data.token;
this.username = username;
this.lastTokenRefreshAt = new Date();
this.saveUserToken();
});
}
您可以在调用登录的组件中捕获错误。
更新到 angular6 并使用新版本的 RxJs 后,我不得不更改 do 方法,因为它是 renamed/deprecated。为了获得与 Sonicd300 的答案类似的结果,我必须使用带管道的 tap 方法:
import { tap } from 'rxjs/operators';
login(username: string, password: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const url = this.apiAddr + '/login';
const body = 'username=' + username + '&password=' + password;
const options = {
headers: headers,
};
return this.http.post<LoginResponse>(url, body, options).pipe(
tap(
data => {
this.jwtoken = data.token;
this.username = username;
this.lastTokenRefreshAt = new Date();
this.saveUserToken();
return 'Login successful';
})
);
}