你好,我有一个嵌套订阅,我以下面的方式处理,听说这是一个不好的方法。
有人可以让我知道最好的方法吗?它将真的帮助我学习。下面是我的代码,请看看。 TIA
login.ts
login(email: string, password: string) {
const user = new FormData();
user.append("username", email);
user.append("password", password);
this.http
.post<any>("api1", user)
.subscribe((response) => {
this.myToken = response.access_token;
console.log(this.myToken);
if (this.myToken) {
const body = new HttpParams()
.set("username", email)
.set("password", password);
return this.http
.post<any>("api2", body, {
headers: new HttpHeaders({
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `${this.myToken}`,
})
})
.subscribe((response) => console.log(response));
} else {
alert("error: Not authorized");
}
});
}
2)加载组件后,我需要检查我的get api响应。如果我得到get API
response == null
,则需要使用相同的表单发布数据。当我获得API response != null
时,我需要将值修补到表单,并且应该能够使用PUT API
form.ts
getVal() {
http.get<any>(API).subscribe(response => {
this.getResponse= response;
if (this.getResponse != null) {
this.form.patchValue({. //append the values to the form
username: response.username,
})
})
}
onRegisterSubmit(form) {
this.username = form.value
console.log(form.value);
if (this.getResponse != null) {
//I want to enable update button and update api here
http.put<any>(api, this.username).subscribe(resposne =>
console.log(response) )
} if(response == null) {
http.post<any>(api, this.username).subscribe(resposne =>
console.log(response) )
//I want to send data using post method.
}
}
答案 0 :(得分:1)
嵌套订阅是不好的,因为会有多个没有直接依赖性的订阅,这将导致更多潜在的内存泄漏。您需要使用RxJS高阶运算符(例如switchMap
)来组合多个可观察对象。尝试以下
import { EMPTY } from 'rxjs';
import { switchMap } from 'rxjs/operators';
login(email: string, password: string) {
const user = new FormData();
user.append("username", email);
user.append("password", password);
this.http.post<any>("api1", user).pipe(
switchMap((response) => {
this.myToken = response.access_token;
console.log(this.myToken);
if (this.myToken) {
const body = new HttpParams().set("username", email).set("password", password);
const headers = new HttpHeaders({
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `${this.myToken}`
});
return this.http.post<any>("api2", body, { headers: headers });
} else {
alert("error: Not authorized");
return EMPTY;
}
})
).subscribe(
(response) => { console.log(response) },
(error) => { }
);
}
在onRegisterSubmit()
函数中,我们检查this.getResponse
变量是否已定义,但在getVal()
函数中异步为其分配了一个值。
onRegisterSubmit(form) {
this.username = form.value;
console.log(form.value);
if (this.getResponse) { // <-- implies `this.getResponse` is already assigned in `onRegisterSubmit()` function
http.put<any>(api, this.username).pipe(
switchMap(putResponse => {
console.log(putResponse);
if(!putResponse) {
return http.post<any>(api, this.username);
}
return EMPTY;
})
).subscribe(
postResponse => { console.log(Postresponse) },
error => { }
);
}
}
switchMap()
运算符应返回一个可观察值。因此,如果没有可观察到的返回值,则可以使用RxJS EMPTY
常量。它创建一个可观察对象,并立即发出完整的通知。
要有条件地订阅一个可观察对象,可以使用RxJS iif
方法。
onRegisterSubmit(form) {
this.username = form.value;
console.log(form.value);
iif(() =>
this.getResponse,
http.put<any>(api, this.username),
http.post<any>(api, this.username)
).subscribe(
respone => { console.log(response) },
error => { }
);
}
答案 1 :(得分:0)
您的最后一个疑问。您不需要包装Put
,因为this.getResponse
是不可观察的值,因此使用if and else
条件比使用任何Rxjs运算符更好。使用if and else
不是onRegisterSubmit method
的嵌套订阅。
或者您可以像使用它
onRegisterSubmit(form) {
this.username = form.value;
iif(() =>
this.getResponse,
http.put<any>(api, this.username),
http.post<any>(api, this.username)
).subscribe(
respone => { console.log(response) },
error => { }
);
}