Julián Bonilla
Julián Bonilla

Reputation: 385

Why is this forEach function repeating last value in all elements?

Look at this code:

var machines = [{
  "name": "inclinedPlane",
  "images": {
    "draggable": {
      "src": "@@instanceAssets/assets/images/mc_inclinedPlane.png",
      "sound": "@@instanceAssets/assets/audios/inclinedPlane.mp3"
    },
    "drop": {
      "default": "@@instanceAssets/assets/images/inclinedPlaneSong.png",
      "onDrop": "@@instanceAssets/assets/images/inclinedPlaneSongFilled.png"
    }
  }
},
{
  "name": "pulley",
  "images": {
    "draggable": {
      "src": "@@instanceAssets/assets/images/mc_pulley.png",
      "sound": "@@instanceAssets/assets/audios/pulley.mp3"
    },
    "drop": {
      "default": "@@instanceAssets/assets/images/pulleySong.png",
      "onDrop": "@@instanceAssets/assets/images/pulleySongFilled.png"
    }
  }
},
{
  "name": "lever",
  "images": {
    "draggable": {
      "src": "@@instanceAssets/assets/images/mc_lever.png",
      "sound": "@@instanceAssets/assets/audios/lever.mp3"
    },
    "drop": {
      "default": "@@instanceAssets/assets/images/leverSong.png",
      "onDrop": "@@instanceAssets/assets/images/leverSongFilled.png"
    }
  }
}];

var drops = {
  "component": "DropContainer",
  "parent": "main",
  "style": {
    "type": "image",
    "scale": { "x": 1, "y": 1 }
  }
};

I want to assign the the default value of each machine drop image to the src attribute of the merged object's style.

machines.forEach((machine) => {
    const config = Object.assign(machine.images.drop, drops);
    config.style.src = machine.images.drop.default;
    console.log(config);
});

But for some reason, thesrc value on each object's style is always being the last one for all objects. I can't see why is this happening and I've spent a lot of time on this with no results. Can you see what's going on here?

Upvotes: 2

Views: 256

Answers (2)

Randy Casburn
Randy Casburn

Reputation: 14165

Here is the output after this simple change:

You already have the default property on the config object (in the root). You obtained it when you created your "merged" object. So...

Change

config.style.src = machine.images.drop;

To

config.style.src = config.default;

And that produces this output:

config.style.src: @@instanceAssets/assets/images/inclinedPlaneSong.png
config.style.src: @@instanceAssets/assets/images/pulleySong.png
config.style.src: @@instanceAssets/assets/images/leverSong.png

========================================

var machines = [{
  "name": "inclinedPlane",
  "images": {
    "draggable": {
      "src": "@@instanceAssets/assets/images/mc_inclinedPlane.png",
      "sound": "@@instanceAssets/assets/audios/inclinedPlane.mp3"
    },
    "drop": {
      "default": "@@instanceAssets/assets/images/inclinedPlaneSong.png",
      "onDrop": "@@instanceAssets/assets/images/inclinedPlaneSongFilled.png"
    }
  }
},
{
  "name": "pulley",
  "images": {
    "draggable": {
      "src": "@@instanceAssets/assets/images/mc_pulley.png",
      "sound": "@@instanceAssets/assets/audios/pulley.mp3"
    },
    "drop": {
      "default": "@@instanceAssets/assets/images/pulleySong.png",
      "onDrop": "@@instanceAssets/assets/images/pulleySongFilled.png"
    }
  }
},
{
  "name": "lever",
  "images": {
    "draggable": {
      "src": "@@instanceAssets/assets/images/mc_lever.png",
      "sound": "@@instanceAssets/assets/audios/lever.mp3"
    },
    "drop": {
      "default": "@@instanceAssets/assets/images/leverSong.png",
      "onDrop": "@@instanceAssets/assets/images/leverSongFilled.png"
    }
  }
}];

var drops = {
  "component": "DropContainer",
  "parent": "main",
  "style": {
    "type": "image",
    "scale": { "x": 1, "y": 1 }
  }
};

machines.forEach((machine) => {
    const config = Object.assign(machine.images.drop, drops);
    config.style.src = config.default;
    console.log('config.style.src: ' + config.style.src);
});

Upvotes: 0

Ele
Ele

Reputation: 33726

  • You need to put the drops object inside of function forEach.

    The problem you're facing is the reference of the same object drops in every assign you're executing.

  • Set the default value as follow: config.style.src = machine.images.drop.default;

var machines = [{    "name": "inclinedPlane",    "images": {      "draggable": {        "src": "@@instanceAssets/assets/images/mc_inclinedPlane.png",        "sound": "@@instanceAssets/assets/audios/inclinedPlane.mp3"      },      "drop": {        "default": "@@instanceAssets/assets/images/inclinedPlaneSong.png",        "onDrop": "@@instanceAssets/assets/images/inclinedPlaneSongFilled.png"      }    }  },  {    "name": "pulley",    "images": {      "draggable": {        "src": "@@instanceAssets/assets/images/mc_pulley.png",        "sound": "@@instanceAssets/assets/audios/pulley.mp3"      },      "drop": {        "default": "@@instanceAssets/assets/images/pulleySong.png",        "onDrop": "@@instanceAssets/assets/images/pulleySongFilled.png"      }    }  },  {    "name": "lever",    "images": {      "draggable": {        "src": "@@instanceAssets/assets/images/mc_lever.png",        "sound": "@@instanceAssets/assets/audios/lever.mp3"      },      "drop": {        "default": "@@instanceAssets/assets/images/leverSong.png",        "onDrop": "@@instanceAssets/assets/images/leverSongFilled.png"      }    }  }];

machines.forEach((machine) => {
  var drops = {    "component": "DropContainer",    "parent": "main",    "style": {      "type": "image",      "scale": {        "x": 1,        "y": 1      }    }  };
  
  const config = Object.assign(machine.images.drop, drops);
  config.style.src = machine.images.drop.default;
});

console.log(JSON.stringify(machines, null, 2))
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Related Questions