0

我想知道,在服务处理响应(保存令牌)后,如何使用新的 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);
 }

通过使用新模块,我不确定如何返回 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,我可以在其中导航到不同的页面。

4

2 回答 2

2

当组件像这样调用它时,使用 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();
  });
}

您可以在调用登录的组件中捕获错误。

于 2017-09-18T20:38:39.287 回答
2

在更新到 Angular 6 并使用新版本的 RxJs 后,我不得不更改 do 方法,因为它已被重命名/弃用。为了达到与 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';
      })
  );
}
于 2018-09-26T18:36:35.340 回答