0

I'm quite new to JS, so excuse me if the question is overly complicated and probably a duplicate, but this problem bugged me for quite some time now and I couldn't find a satisfying answer or solution.

I have an array of Objects, where I want to change some properties based on another array of the same length. I thought this would be easily done in a for-loop, but to my surprise all properties end up having the same value.

Here is the array of Objects (dattmp) and the other array (color):

var testdat = {
    Element1: {time: [1586777601886.39, 1586777608597.8, 1586777615309.21]},
    Element2: {time: [1586777603886.39, 1586777638597.8, 1586777315309.21]}
}
var options = {pathOptions: {className: "myclass"}}

var dattmp = [];
for (kys in testdat) {
    var tmp = {
      type: "Feature",
      properties: {
          time: testdat[kys].time,
          path_options: options.pathOptions
      }
    };
    dattmp.push(tmp);
}

var color = ["orange", "blue"];

My goal is to include the color in dattmp, so that the first Objects color is orange and the second one blue.

I tried a normal for-loop and a map but both color properties end up being blue.

for (var i = 0; i < color.length; i++) {
    dattmp[i].properties.path_options.color = color[i];
}

const newdat = dattmp.map((dt, i)  => {
    dt.properties.path_options.color = color[i];
    return dt;
});

The following would work, but my IDE tells me there are a lot of problems with this code, and I don't really understand the ... notation. So my question is: What is the correct approach to changing the values individually?

const newdat1 = dattmp.map((dt, i)  => {
    dt = { ...dt, properties: {...dt.properties, path_options: {...dt.properties.path_options, color: color[i]}}};
    return dt;
});
1

2 Answers 2

1

Issue is options.pathOptions refer to thee same object in both elements of the array. Since it's just a reference, modifying it modifies it on all elements of the array. To copy , try Object.assign

var testdat = {
  Element1: { time: [1586777601886.39, 1586777608597.8, 1586777615309.21] },
  Element2: { time: [1586777603886.39, 1586777638597.8, 1586777315309.21] },
};
var options = { pathOptions: { className: 'myclass' } };

var dattmp = [];
for (kys in testdat) {
  var tmp = {
    type: 'Feature',
    properties: {
      time: testdat[kys].time,
      path_options: Object.assign({}, options.pathOptions),
    },
  };
  dattmp.push(tmp);
}
var color = ['orange', 'blue'];

for (var i = 0; i < color.length; i++) {
  dattmp[i].properties.path_options.color = color[i];
}
console.log(dattmp);

Sign up to request clarification or add additional context in comments.

Comments

1

Check this one:

const dattmp = [];


const color = ["orange", "blue"];

for (let i = 0; i < color.length; i += 1) {
  const obj = {
    properties: {
      path_options: {
        color: color[i],
      },
    },
  };
  dattmp.push(obj);
}

The problem is that you're trying to read properties from an empty array.

Edit: If you want to preserve other properties, you can use this:

const newdat1 = dattmp.map((dt, i) => {
  const obj = {
    ...dt,
    properties: {
      ...dt.properties,
      path_options: { ...dt.properties.path_options, color: color[i] },
    },
  };
  return obj;
});

3 Comments

But I want to keep the other properties type, time etc and just add/change the color property.
Yeah that is exactly what I am using right now. Is that really the most elegant way to change a property?
@SeGa I don't really know what your use case is. but I don't think there is any neater way for what you want to achieve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.