0

I have a function that contains the following code:

stores = [];
console.log('in stores d.length is ', districts.length);
districts.forEach( function ( dis ) {
    dis.store.forEach( function( store ) {
        store.structure = dis.structure;
        store.structure.dis = dis.district_nbr;
        store.structure.sto = store.store_nbr;
        //store.message = getMessage(store.structure);
        console.log('store st is ', store.structure);
        stores.push( store );
    });
});
stores.forEach( function ( s ) {
    console.log("after set Master this is stores ", s.structure);
})

As the loops go, I initialize an object structure for each store starting out as the structure from the parent dis object which has a few fields and has been validated as correct. I then add an additional fields to the structure object to account for the district number and store number. Each dis object has a unique set of stores.

The console.log in the nested for loops displays the correct structure for the store. However, when I print them after the fact, the stores all have the final district number in the loop and the final store number in the loop instead of their respective correct values.

QUESTION: Does something happen in Array.push() that I'm not aware of that through things out of whack? I think my real question is what am I missing?

discodane
  • 1,978
  • 4
  • 24
  • 37

3 Answers3

3

You need to clone the dis.structure to avoid modifying the same object in each iteration of the loop.

function clone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

stores = [];
console.log('in stores d.length is ', districts.length);
districts.forEach( function ( dis ) {
    dis.store.forEach( function( store ) {
        store.structure = clone(dis.structure);
        store.structure.dis = dis.district_nbr;
        store.structure.sto = store.store_nbr;
        //store.message = getMessage(store.structure);
        console.log('store st is ', store.structure);
        stores.push( store );
    });
});
stores.forEach( function ( s ) {
    console.log("after set Master this is stores ", s.structure);
})

For more on deep-cloning objects, see this answer on stack overflow.

Community
  • 1
  • 1
Kenan Banks
  • 207,056
  • 34
  • 155
  • 173
2

The problem is that when you set store.structure = dis.structure, store.structure is now a reference to dis.structure, not a copy.

This means that every time you then mutate store.structure, you are in fact mutating the dis.structure.

Aron
  • 8,696
  • 6
  • 33
  • 59
1

Your dis.store's items are same as stores items, because your stores's items are not values but references. So you put same references into 2 different arrays. And if you change the items from one reference, it will be updated also for the another one.

You need to copy them with Object.assign, but be aware it will copy only first level items Replace this line store.structure = dis.structure; with this store.structure = Object.assign({}, dis.structure);

Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112