Empty result after execute first observable subscribe inside foreach to end

Hi,
I’m using ionic 3, angular 5,
I’m not sure what’s wrong with my code, I have the result always empty of observable inside foreach. Here’s my code:

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.ardstksoc < element.amount ){
				//change boolean status quantity is valid
				article.plvqtyisvalid = false;
			  }
			  
			  //method changes the contents of array
			  this.articlepanier.splice(index, 0, 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 card in database 
		}
	  
	  });

I want the result of observable inside foreach but this.articlepanier is always empty

This is far and away the most common problem I encountered when I was new to reactive programming, and it’s hard to explain fully in terms that make sense then.

So, while you wait for better answers, I’m going to describe some rules that I’d like you to consider following, that borrow from the world of functional programming.

First, check out this post for some terminology. Once you write this.storage.get, there should be no other statements at that level. That has to be it. You can (and should, if you care about returning anything out of here, which it sounds like you do) put a return before this.storage.get. That, incidentally, is the only way that you should be attempting to affect anything external. Which means that this line: this.articlepanier.splice(index, 0, article); has to go. No modifying external state from inside here.

It sounds like you are trying to build an array of Articles. I would make Article an interface instead of a class, but that’s another discussion. You cannot return an Article[] out of here, period. You can return a Promise<Article[]>, you can return an Observable<Article[]>, but you cannot return an Article[]. The way you have it now is fundamentally relying on the ability to return a synchronous result from an asynchronous function.

So rewrite everything you have here with the following constraints:

  • break it down into as many functions as you like, but the first word of each must be return
  • declare return value types for each function - no any whatsoever
  • do not reference this in any of them, except for immutable helper objects that are injected in the constructor - all variable data needed must be explicitly passed to the function
1 Like

Thank you, that’s very helpful indeed, I will try this!