1

I have the TS code

getItems().subscribe(val=>{
this.items=val;
})

which works fine. When I console.log(this.items) I get

"array:0{size:XL,quantity:1}"

Buuut. Amazingly, something I've never dealt with before in angular, when I run the code in the html template of

<div *ngFor="let item of items">
{{item.size}}
</div

items =[{size:'XL',quantity:4}] I get ABSOLUTELY NOTHING. This is really bizzarre because I've written hundreds of these statements and have never had this issue before. Please help me.

Solved:

What I've figured out is that calling getItems() with a subject, where the getItems method returns a subject "asobservable" can ONLY be done in the same component, directly after the subject is populated. Populating a subject prior to page change seems to still allow the data to be transferred enough to log in console, but not to be usable by the greater application.

So therefore doing

updateItems(items);
getItemsUpdated().subscribe(val=>{
this.items=val
})

where there is a subject and

updateItems(items:items){
this.subject.next(items)
}
getItemsUpdated(){
return this.subject.asObservable()
}

would Work, but only when called directly next to each other in the same component.
Since in this case I was updating the subject, switching pages, and then calling the subject, I was experiencing a weird sort of subject limbo where the console was still able to record the value passed to the subject, but it was not being resolved fully by the receiving component, and therefore was not functioning with the *ngFor.

Correct Flow

updateItems(items);
---------->Navigate to next page-------->
getItemsUpdated().subscribe(val=>{
this.items=val
})

where there is a behaviorSubject and

updateItems(items:items){
this.behaviorSubject.next(items)
}

getItemsUpdated(){
return this.behaviorSubject.asObservable()
}

For this case, using a BehaviorSubject instead of Subject allowed the data to be process "on time" correctly and work with the app. Thanks everybody for your input!

2 Answers2

0

Your stackblitz doesnt allow ngFor so the setup must be wrong. Here is what I think is the problem:

Your app has a weird data flow, when you subscribe to your observable, you wont receive any data until something calls next on your subject. What you seems to be doing from what I've seen in your stackblitz is:

  1. Call to update which is going to to give a value to your Subject
  2. You subscribe and its already too late

You can't get the last value from a subject and since you subsribed too late, your console.log from the subscribe is never actually doing anything. You are seeing the console.log related to your update(the one from hello component)

ukn
  • 1,723
  • 1
  • 14
  • 24
  • This is in line with the opinion I should try a behaviorsubject. The error in the stackblitz is a bit different in appearance, but possibly the same as the one I'm getting in my app. The reason I'm weary about this is that in my app the subscription is working perfectly fine in the next page. I will try a BehaviorSubject and let you know how that works. – Jon Atollah May 26 '21 at 20:50
  • You were correct in your thinking! I was aware it must be something of this sort, but what I've figured out is that calling getItems() with a subject, where the getItems method returns a subject "asobservable" can ONLY be done in the same component, directly after the subject is populated. Populating a subject prior to page change seems to still allow the data to be transferred enough to log in console, but not to be usable by the greater application. I'm going with the other person though because he gave me the exact solution. – Jon Atollah May 26 '21 at 20:57
0

You should be using a BehaviorSubject or a ReplaySubject; plain Subject will only give you the values emitted after the subscription.

export class CartService {
  public cartUpdated: Subject<Item[]> = new BehaviorSubject([]);

More info in: Subject vs BehaviorSubject vs ReplaySubject in Angular

Fixed Stackblitz

eko
  • 39,722
  • 10
  • 72
  • 98
  • Allow me to test this in my context and get back to you on whether or not it makes a difference. – Jon Atollah May 26 '21 at 20:48
  • Thank you so much! as I told the other person: what I've figured out is that calling getItems() with a subject, where the getItems method returns a subject "asobservable" can ONLY be done in the same component, directly after the subject is populated. Populating a subject prior to page change seems to still allow the data to be transferred enough to log in console, but not to be usable by the greater application. Your advice to use BehaviorSubject has solved this issue. Thank you very much. – Jon Atollah May 26 '21 at 20:58
  • Glad I could help :-) – eko May 26 '21 at 21:00