对于JWT身份验证,我发布了一个发布请求,以使用现在使用Observables的新Http
模块来获取令牌。
我有一个简单的Login
组件,显示表单:
@Component({
selector: 'my-login',
template: `<form (submit)="submitForm($event)">
<input [(ngModel)]="cred.username" type="text" required autofocus>
<input [(ngModel)]="cred.password" type="password" required>
<button type="submit">Connexion</button>
</form>`
})
export class LoginComponent {
private cred: CredentialsModel = new CredentialsModel();
constructor(public auth: Auth) {}
submitForm(e: MouseEvent) {
e.preventDefault();
this.auth.authentificate(this.cred);
}
}
我有一个Auth
服务提出请求:
@Injectable()
export class Auth {
constructor(public http: Http) {}
public authentificate(credentials: CredentialsModel) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
.map(res => res.json())
.subscribe(
data => this._saveJwt(data.id_token),
err => console.log(err)
);
}
}
运行良好但现在我想在我的组件中显示错误消息,因此我需要在2个位置订阅(Auth
用于管理成功,Login
用于管理错误。
我使用share
运算符实现了它:
public authentificate(credentials: CredentialsModel) : Observable<Response> {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
const auth$ = this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
.map(res => res.json()).share();
auth$.subscribe(data => this._saveJwt(data.id_token), () => {});
return auth$;
}
在组件内部:
submitForm(e: MouseEvent) {
e.preventDefault();
this.auth.authentificate(this.cred).subscribe(() => {}, (err) => {
console.log('ERROR component', err);
});
}
它有效,但我觉得做错了..
我只是通过angular1和promises
转换我们的方式,您是否看到更好的方法来实现它?
答案 0 :(得分:6)
如果可以使用此方法,为什么要在sharedService
中订阅!
@Injectable()
export class Auth {
constructor(public http: Http) {}
public authentificate(credentials: CredentialsModel) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers}) //added return
.map(res => res.json());
//.subscribe(
// data => this._saveJwt(data.id_token),
// err => console.log(err)
//);
}
}
@Component({
selector: 'my-login',
template: `<form (submit)="submitForm($event)">
<input [(ngModel)]="cred.username" type="text" required autofocus>
<input [(ngModel)]="cred.password" type="password" required>
<button type="submit">Connexion</button>
</form>`
})
export class LoginComponent {
private cred: CredentialsModel = new CredentialsModel();
constructor(public auth: Auth) {}
submitForm(e: MouseEvent) {
e.preventDefault();
this.auth.authentificate(this.cred).subscribe(
(data) => {this.auth._saveJwt(data.id_token)}, //changed
(err)=>console.log(err),
()=>console.log("Done")
);
}
}
<小时/> 编辑
sharedService
和component
订阅,您肯定会采用这种方法。 但我不推荐这个 ,而不是在编辑部分之前对我来说是完美的。
我无法使用您的代码进行测试。但看看我的example here(tested)。单击myFriends tab
,检查浏览器控制台和UI。浏览器控制台显示sharedService
&amp;的订阅结果UI显示component
的订阅结果。
@Injectable()
export class Auth {
constructor(public http: Http) {}
public authentificate(credentials: CredentialsModel) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
var sub = this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers}) //added return
.map(res => res.json());
sub.subscribe(
data => this._saveJwt(data.id_token),
err => console.log(err)
);
return sub;
}
}
export class LoginComponent {
private cred: CredentialsModel = new CredentialsModel();
constructor(public auth: Auth) {}
submitForm(e: MouseEvent) {
e.preventDefault();
this.auth.authentificate(this.cred).subscribe(
(data) => {this.auth._saveJwt(data.id_token)}, //not necessary to call _saveJwt from here now.
(err)=>console.log(err),
()=>console.log("Done")
);
}
}
答案 1 :(得分:2)
您只能订阅服务中的事件并返回相应的observable:
public authentificate(credentials: CredentialsModel) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
var obs = this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
.map(res => res.json())
.subscribe(
data => this._saveJwt(data.id_token)
);
return obs;
}
如果发生错误,您可以使用catch
运算符捕获它:
submitForm(e: MouseEvent) {
e.preventDefault();
this.auth.authentificate(this.cred).catch((err) => {
console.log('ERROR component', err);
});
}
修改强>
如果你想两次订阅一个observable,你需要让它&#34; hot&#34;通过调用share
方法。
您还可以利用do
运算符,只在组件中订阅:
public authentificate(credentials: CredentialsModel) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post(config.LOGIN_URL, JSON.stringify(credentials), {headers})
.map(res => res.json())
.do(
data => this._saveJwt(data.id_token)
);
}