Angular2:サービスおよびコンポーネント内で監視可能なHttp.postを適切にサブスクライブする方法は?
JWT認証の場合、Observablesで動作する新しいHttp
モジュールを使用して、トークンを取得するためのPOSTリクエストを作成します。
フォームを表示する単純な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
を使用して行った方法を転置するだけですが、それを達成するためのより良い方法がわかりますか?
サービスのイベントにサブスクライブして、対応するオブザーバブルのみを返すことができます。
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);
});
}
編集
オブザーバブルを2回サブスクライブしたい場合は、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)
);
}