1

I've a very strange issue in my angular application.


// these are class attributes
  tenants: any[] = [];
  @Input() onTenantListChange: EventEmitter<Tenant[]>;



  ngOnInit(): void {

    this.onListChange.subscribe(data => {
      if (data !== undefined && Array.isArray(data)) {
        console.log("iniziale", data)
        this.tenants = [];
        for (let t of data) {
         console.log(" t ",t)
         this.tenants.push({
            title: t.name,
            value: t.id,
          });
        }
        console.log(this.tenants);
      }
    });
  }

While the first console log shows the updated list, the console.log(" t ",t) shows different value (the previous value of that element, also if i've reinitialized the list to [] befor assigning new values. After two invocation of this event, the edit is captured

enter image description here As you can see, the Firefox console shows "old value" as the preview, but if I expand the log message, there is the correct value inside

Note: insertion and delete in the data array works, the problem comes when i want to update an existing element

There are of course some walkaround ( I can duplicate the onListChange event trigger), but I cant' figure out where is the real problem whit this loop

Thank you very much for your suggestions

I expect that the console.log inside the for loop shows the same element than the console.log("iniziale", data) I've tyed different type of loop: for (let a of data) data.foreach() for (let i = 0; i< data.length; i++) {}

The output is the same

  • On the issue of “old value” in preview and “updated value” when expanded, you can look at the following answer. As for modifying the array and resetting it, I’m assuming there are other references to this.tenants which might be causing the issue, how about trying this.tenants.length = 0 to clear the array?https://stackoverflow.com/questions/11284663/console-log-shows-the-changed-value-of-a-variable-before-the-value-actually-ch – Jason Nov 07 '22 at 16:35
  • How many times is the `ngOnInit` being called? Also, can you try using a Subject instead of an input to see if something changes? – Jacopo Sciampi Nov 07 '22 at 18:06
  • @Jason I've tryed to substitute the this.tenant with a new local variable, but the result is the same. Your linkd question was usefull, since if I print the data variable with JSON(data,null,2), it is not updated --> so the problem is not the loop but the event, as Vaira sad in his answer JacopoSciampi ngOnInit is called only at page load, once – Francesco Cencioni Nov 08 '22 at 17:52

1 Answers1

0

The value gets updated after your subscribe code executes, so onListChange is getting triggered before the latest data is updated.

Browser Object is pointing to the reference of data so it gets updated on expansion. It would be more clear if you wrote "console.log(" t ",t.name)"

Either call "this.onListChange" only after it has got updated value or if its out of your hand, add a delay to give it time to update eg: this.onListChange.pipe(delay(300)).subscribe...

 this.onListChange.subscribe(data => { // this data is not updated yet and has old value
         console.log(" t ",t.name)  
    });


  this.onListChange.pipe(delay(300)).subscribe(data => { // this should update the data, if not try increasing time
             console.log(" t ",t.name)  
        });
vaira
  • 2,191
  • 1
  • 10
  • 15
  • you are right, it is a timing problem, using console.log(JSON.stringify(data,null,2) it shown the old values. Is there a better way than add a fixed delay? – Francesco Cencioni Nov 08 '22 at 17:53
  • setTimeout can also be used (but its not better), if delay is bad you can basically look for a better even to trigger onListChange, an event that is triggered after the values in `data` is updated. – vaira Nov 09 '22 at 10:51