1

I am trying to update a specific array index with a new carrier_id and name.

However, I'm getting a puzzling assignment problem.

Comment line with Note #1 out and nData will look fine, otherwise its order property appears to get set before updateNormalizedData is called.

let data = JSON.parse('[{"order":{"po_no":"po_2019","ship_details":{"carrier_id":1044777,"method":"FREE Shipping"},"sub_total":0},"items":[{"header":{"set_no":0,"carrier_id":104777,"po_no":"po_2019"},"line":{"item_id":"ABC RE1000","line_no":0}},{"header":{"set_no":0,"carrier_id":104777,"po_no":"po_2019"},"line":{"item_id":"ABC DA1111","line_no":1}}]}]');
let numSet = 0;
let numLine = 1;
let args = {"carrier_id": 555111};

function normalizeData(data, numSet, numLine, args) {
  let i = 0, j = 0, l = data.length;
  let normalizedDataSet = [];

  // console.log(data[i])

  for (i = 0; i < l; i++) {
    let m = data[i]['items'].length;
    for (j = 0; j < m; j++) {
      data[i]['items'][j]['order'] = { ...data[i]['order'] }; // Destructure data to assign value, not object reference
      normalizedDataSet.push(data[i]['items'][j]);
    }
  }

  // console.log('nData',  normalizedDataSet);
  updateNormalizedData(normalizedDataSet, numSet, numLine, args); // Note #1
}

function updateNormalizedData(normalizedDataSet, numSet, numLine, args) {
  let i;
  let n = normalizedDataSet.length;
  let newNormal = [];

  for (i = 0; i < n; i++) {
    let index = { ...normalizedDataSet };

    if (numSet === index[i]['header']['set_no'] && numLine === index[i]['line']['line_no']) {
      let shipMethods = JSON.parse('[{"id":103366,"name":"FREE Shipping"},{"id":200200,"name":"BEST"},{"id":555111,"name":"COLLECT"}]');
      let shipMethod = shipMethods.filter(item => { return item.id === args.carrier_id }); // [0]['name'];
      console.log("date_updated this index", i);
      index[i]['order']['ship_details']['carrier_id'] = args.carrier_id;
      index[i]['order']['ship_details']['method'] = shipMethod[0]['name'];
      newNormal.push(index[i]); // Should update order.ship_details.carrier_id
    } else {
      console.log("Use original index");
      newNormal.push(normalizedDataSet[i]); // Should NOT update order.ship_details.carrier_id
    }
  }

  console.log('new normal', JSON.stringify(newNormal));
}

normalizeData(data, numSet, numLine, args);

I'm not sure how the property is getting assigned "before" a function is called that assigns it.

I'm guessing it may have something to do with the data destructuring, but I'm not certain.

Any guidance / help is greatly appreciated.

In this example I'm trying to update just { "setNo": 0, "lineNo": 1 } with new normal order data, but both lines 0 and 1 are being set.

Matthew
  • 1,461
  • 3
  • 23
  • 49
  • I'm not 100% sure what's supposed to happen, but you aren't changing anything in this test between loops: `if (args.carrier_id)` `args` is passed into the function, so in the loop, this will either always be true or always be false. – Mark Jun 22 '19 at 20:19
  • Now deleted. That was an unncessary artifact... – Matthew Jun 22 '19 at 20:22
  • The first time through the loop it `setNo` and `lineNo` should not match so it pushes the first index unchanged. The second time through it should enter and update the `carrier_id` properties. – Matthew Jun 22 '19 at 20:23
  • Can you explain this further? I thought push was supposed to create a new array index... – Matthew Jun 22 '19 at 20:32
  • When I log `newNormal[0]['items']` is `undefined` (my intention). – Matthew Jun 22 '19 at 20:36
  • Sorry…my mistake. – Mark Jun 22 '19 at 20:40
  • It's all good. Thanks for taking a look! – Matthew Jun 22 '19 at 20:48
  • 2
    Ok -- the problem is this doesn't make a deep copy `{ ...data[i]['order'] }`. You end up with the same reference to `data[0]['order']['ship_details']` in both items of you normalized data. You later mutated them, but since it's the same object they all change and only the last change is reflected. In other words: `normalizedDataSet[0]['order']['ship_details'] === normalizedDataSet[1]['order']['ship_details']` – Mark Jun 22 '19 at 21:02
  • I'm a bit confused. Do you have an example or good resource? I thought destructuring was supposed to make a deep copy. – Matthew Jun 22 '19 at 21:17
  • 1
    `JSON.parse(JSON.stringify(data[i]['order']))` seems to work... – Matthew Jun 22 '19 at 21:19
  • There is no destructuring in the code you've shown. Are you referring to the object spread syntax? – Bergi Jun 22 '19 at 21:24
  • @Bergi I must be... I thought `{ ...data[i]['order'] }` was destructuring. Would destructuring be a valid solution? Is the nested JSON syntax destructuring? – Matthew Jun 22 '19 at 21:26
  • @Bergi Here is the reference for why I was trying to use the `...` syntax. https://stackoverflow.com/questions/56563328/how-to-set-array-index-of-normalized-data – Matthew Jun 22 '19 at 21:27
  • @Matthew No, that post did use term totally wrong. [I've fixed it](https://stackoverflow.com/posts/56564811/revisions). See [here](https://stackoverflow.com/q/26999820/1048572) to learn about destructuring (but no, it won't help in this case). – Bergi Jun 22 '19 at 21:33
  • @Bergi Would `JSON.parse(JSON.stringify(data[i]['order']))` be a good method for creating a deep copy in this case? – Matthew Jun 22 '19 at 21:38

0 Answers0