vincentmorneau / json-mapping

Change the structure of an existing JSON object with this mapping module

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

It's not possible to use "values" for more than one element in array

loebelch opened this issue · comments

json-mapping version 1.1.4 (latest)

My mappingtable contains two elements in "values"-array:

[
  {
    "oldKey": "mykey",
    "newKey": "myNewKey",
    "values": [
      {
        "oldValue": 1,
        "newValue": "Number 1"
      },
      {
        "oldValue": 2,
        "newValue": "Number 2"
      }
    ]
  }
]

But the values were only replaced, if there is a match in the 2nd element.

Example:

  • Result for a JSON { "mykey": 1} will be empty => {}
  • But a JSON { "mykey": 2} will be mapped/replaced correctly to { myNewKey: 'Number 2' }

So how is it possible to replace more than one value?

Complete code:

const mapping = require('json-mapping');

let json1 = {
       "mykey": 1
};

let json2 = {
       "mykey": 2
}

let mappingtable = [
    {
        oldKey: "mykey",
        newKey: "myNewKey",
        values: [ {"oldValue": 1, "newValue": "Number 1" },{ "oldValue": 2, "newValue": "Number 2" }]
    }
];

let result1 = mapping.map(json1, mappingtable);
let result2 = mapping.map(json2, mappingtable);

console.log("result 1:");
console.log(result1);
console.log("result 2:");
console.log(result2);

Result:

node test.js

result 1:
{}
result 2:
{ myNewKey: 'Number 2' }

Found the reason:

Object.keys(values).forEach(value => { if (oldKeyValue === values[value].oldValue) { newKeyValue = values[value].newValue; } else { newKeyValue = undefined; } });
forEach loops through the whole array. If the first element has a match it will be set as newKeyValue - but forEach doesn't stops and so after the 2nd element is running through the loop - newKeyValue is set back to undefined.

My solution - change the forEach loop to a classical loop and add a "break" if there is a match:
for (let value = 0; value < values.length; value++) { if (oldKeyValue === values[value].oldValue) { newKeyValue = values[value].newValue; break; } else { newKeyValue = undefined; } }
It's still not perfect, because if there are more elements in the array which matches - only the first match will be used.

Thanks for the solution. If you wish to make a pull request, I'd review and accept.

Thank you!

v1.1.5 pushed to npm