如何处理angular 4 HttpClient';服务和通知组件中的响应

如何处理angular 4 HttpClient';服务和通知组件中的响应,angular,angular-httpclient,Angular,Angular Httpclient,我想知道,在服务处理(保存令牌)响应后,如何通过使用新的HttpClient(angular 4.3+来自@angular/common/http)轻松地通知组件http响应(成功或错误) 之前,我使用了以下代码(使用@angular/http): login(用户名:string,密码:string):可观察{ let headers=新的头({'Content Type':'application/x-www-form-urlencoded'}); let options=newreques

我想知道,在服务处理(保存令牌)响应后,如何通过使用新的HttpClient(angular 4.3+来自@angular/common/http)轻松地通知组件http响应(成功或错误)

之前,我使用了以下代码(使用@angular/http):

login(用户名:string,密码:string):可观察{
let headers=新的头({'Content Type':'application/x-www-form-urlencoded'});
let options=newrequestoptions({headers:headers});
让url=this.apiAddr+'/login';
变量body='username='+username+'&password='+password;
返回此.http.post(url、正文、选项).map((res)=>{
让body=res.json();
this.jwtoken=body.token;
this.username=用户名;
这个.saveToken();
返回“登录成功!”;
})
.接住(这个.把手错误);
}
通过使用新的模块,我不知道如何返回可观察的,同时从服务访问它。这是我目前拥有的(auth.service.ts):

登录(用户名:字符串,密码:字符串){
const headers=new-HttpHeaders().set('Content-Type','application/x-www-form-urlencoded');
const url=apiAddr+'/login';
const body='username='+username+'&password='+password;
常量选项={
标题:标题,
};
this.http.post(url、正文、选项)。订阅(
数据=>{
this.jwtoken=data.token;
this.username=用户名;
this.lastTokenRefreshAt=新日期();
这个.saveUserToken();
},err=>{
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();
  });
}
导入'rxjs/add/operator/do';
登录(用户名:string,密码:string){
const headers=new-HttpHeaders().set('Content-Type','application/x-www-form-urlencoded');
const url=apiAddr+'/login';
const body='username='+username+'&password='+password;
常量选项={
标题:标题,
};
返回this.http.post(url、正文、选项)(
数据=>{
this.jwtoken=data.token;
this.username=用户名;
this.lastTokenRefreshAt=新日期();
这个.saveUserToken();
});
}

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

当组件以如下方式调用服务时,使用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();
  });
}
导入'rxjs/add/operator/do';
登录(用户名:string,密码:string){
const headers=new-HttpHeaders().set('Content-Type','application/x-www-form-urlencoded');
const url=apiAddr+'/login';
const body='username='+username+'&password='+password;
常量选项={
标题:标题,
};
返回this.http.post(url、正文、选项)(
数据=>{
this.jwtoken=data.token;
this.username=用户名;
this.lastTokenRefreshAt=新日期();
这个.saveUserToken();
});
}

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

在更新到angular 6并使用新版本的RxJs后,我不得不更改do方法,因为它被重命名/弃用。为了获得与Sonicd300答案类似的结果,我必须使用管道的抽头方法,因此:

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';
      })
  );
}
从'rxjs/operators'导入{tap};
登录(用户名:string,密码:string){
const headers=new-HttpHeaders().set('Content-Type','application/x-www-form-urlencoded');
const url=this.apiAddr+'/login';
const body='username='+username+'&password='+password;
常量选项={
标题:标题,
};
返回此.http.post(url、正文、选项).pipe(
水龙头(
数据=>{
this.jwtoken=data.token;
this.username=用户名;
this.lastTokenRefreshAt=新日期();
这个.saveUserToken();
返回“登录成功”;
})
);
}

更新到angular 6并使用新版本的RxJs后,我不得不更改do方法,因为它被重命名/弃用。为了获得与Sonicd300答案类似的结果,我必须使用管道的抽头方法,因此:

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';
      })
  );
}
从'rxjs/operators'导入{tap};
登录(用户名:string,密码:string){
const headers=new-HttpHeaders().set('Content-Type','application/x-www-form-urlencoded');
const url=this.apiAddr+'/login';
const body='username='+username+'&password='+password;
常量选项={
标题:标题,
};
返回此.http.post(url、正文、选项).pipe(
水龙头(
数据=>{
this.jwtoken=data.token;
this.username=用户名;
this.lastTokenRefreshAt=新日期();
这个.saveUserToken();
返回“登录成功”;
})
);
}

完美。非常感谢您的快速回复。它按预期工作。完美。非常感谢您的快速回复。它按预期工作。