Object's field called "id" brokes ngFor (?!)


#1

I’m having a problem with ngFor and I don’t know why. Let’s assume that I have an array with just two objects.

<ion-card *ngFor="let something of localService.getStuff()">
   <ion-card-content>
      <strong>{{something.name}}</strong> // This has values "name1" and "name2"
      <br/>{{getData(something.id)}} // This has values 1 and 2.
   </ion-card-content>
</ion-card>

The first time all the data shown is correct, id’s values are 1 and 2. BUT if I go to another screen and come back, then “something.id” values are 2 and 2 again. However, “something.name” is working fine, it still has values “name1” and “name2”.

So, I tried to rename the field “id” to “di” and magic! all the values of “di” are correct! (1 and 2).

The question is… why XXX.id fails?!


#2

Maybe because you missed a closing parenthesis here after something.id?
<br/>{{getData(something.id}} // This has values 1 and 2.

Anyway, I wouldn’t wonder to much about it if you’ve got it fixed. I didn’t encounter such an issue before btw.


#3

No, it’s not the closing parenthesis, that was a mistake writing here.


#4

Guessed so. Why are you directly calling localservice.getStuff inside the ngfor btw? Isn’t it easier to just return it inside your component, and loop over the results?


#5

I don’t need to process the result, so in that way do the job with less boilerplate.


#6

I also think you shouldn’t do this in your template. Use the component for fetching and storing data used in the template.


#7

Return the result from the component doesn’t fix it.


#8

And what does the dumped json says it should be? So if you just do

{{ something | json }} 
inside your template. Does it still distort the id’s when switching views?

#9

If you put a property on the page

stuff:any;
and load it in the page
ionViewDidLoad() { this.stuff = localService.getStuff(); console.log(this.stuff) }
what do you see? Are you sure getStuff doesnt return a promise?


#10

{{ something | json }} shows all fields correct BUT when I come back from the other view, both id are 2. The other fields are ok. I don’t understand why id field changes when I come back but not the other fields.


#11

log shows the correct data and yes, I’m 100% sure. It’s not a promise, just an array.


#12

That’s really weird though. And you’re absolutely sure you don’t manipulate the array whatsoever? What if you just create two different objects inside an array with key-values and use them for testing, still the same issue?


#13

any possibilty you can post the complete template + page code? It looks like you’re subconsciously manipulating the array somewhere


#14

OMG it was a if (something.id = id) instead a if (something.id == id_something) in a method of the service launched on the other screen. So that changed the value in the view, because it’s binded.

I never changed the “id” name in that service’s method, so when I changed the name in my test to “di”, the “if” it was setting nothing, because “id” field didn’t exist. That’s why to change the name fixed it.

With no warnings by the tslint or the VS Code about that mistake, I couldn’t see it until now. Thank you both for make me check the code more closely.

TL;DR I missed an = in other place.

PS: Please, excuse my english.


#15

It happens to all of us.

Also, use === instead of == for safety


#16

found this :slight_smile:

https://palantir.github.io/tslint/rules/no-conditional-assignment/


#17

Installing… :smiley:


#18

I’ve added it to my config too. This type of mistakes can ruin your day