问题描述
我正在使用离子3,角5, 我不确定我的代码有什么问题,我的结果总是在foreach内部无法观察到。这是我的代码:
articlepanier : Article[] = [];
this.storage.get(TOKEN_KEY).then(token => {
let isExpired = helper.isTokenExpired(token);
if(!isExpired){
//foreach loop
this.cart.forEach((element,index) => {
var article = new Article();
article.artid = element.artid;
article.artcode = element.artcode;
//value of the sales unit quantity
article.plvqteuv = element.amount;
let data = {
pricode: this.pricode,artcode: element.artcode
};
//use observable to return stock available in the database
//and change the value of the article.plvqtyisvalid by false value at each line
//if the quantity entered exceeds the quantity available
this.cardProvider.stockbyarticle(data).subscribe((res: any) => {
if( res.quantity < element.amount ){
//change boolean status quantity is valid
article.plvqtyisvalid = false;
}
//method changes the contents of array
this.articlepanier.splice(index,article);
console.log(this.articlepanier);
});
});
//Here outside of foreach,I want the result of array after executing foreach (this.articlepanier) to be used in a if condition
//But articlepanier is always empty
if(this.articlepanier.filter(c =>(c.plvqtyisvalid == true).length > 0){
//recording the cart in database
}
});
我想要在foreach内部观察到的结果,但是this.articlepanier总是空的,在foreach之外是她的
解决方法
我在这里看到多个问题
-
您正在订阅
forEach
。因此,每个元素将构成一个单独的订阅。相反,您可以使用forkJoin
,combineLatest
或zip
之类的RxJS函数来并行订阅多个可观察对象。 -
您正在尝试同步访问异步变量
articlepanier
。您尝试在订阅之外访问它的时间尚未调整。您需要使用switchMap
之类的RxJS运算符来使整个流具有反应性。
尝试以下
import { from,forkJoin } from 'rxjs';
import { filter,map,switchMap } from 'rxjs/operators';
from(this.storage.get(TOKEN_KEY)).pipe(
filter(token => !(helper.isTokenExpired(token))),switchMap(_ => {
return forkJoin(this.cart.map((element,index) => {
const article = new Article();
article.artid = element.artid;
article.artcode = element.artcode;
article.plvqteuv = element.amount; //value of the sales unit quantity
let data = {
pricode: this.pricode,artcode: element.artcode
};
return this.cardProvider.stockbyarticle(data).pipe(
tap((res: any) => {
if (res.quantity < element.amount) { // change boolean status quantity is valid
article.plvqtyisvalid = false;
}
this.articlepanier.splice(index,article); // method changes the contents of array
console.log(this.articlepanier);
})
)
}))
})
).subscribe(
res => {
if (this.articlepanier.filter(c => (c.plvqtyisvalid == true).length > 0)) {
// recording the card in database
}
}
);
请注意,我正在使用RxJS from
函数将this.storage.get(TOKEN_KEY)
函数返回的Promise转换为可观察的。最好与Promises或Observables一起使用,而不要结合使用。我还使用RxJS filter
运算符检查令牌是否仍然有效。