0

I want to convert my JSON to a specific format but not sure what is the best way. I want to make a generic function which I can use commonly. I do not want some code which has hard coded value such as root, Amount, etc.

I am using typeScript and node.

Current:

{
    "elements": [
        {
            "type": "element",
            "name": "root",
            "elements": [
                {
                    "type": "element",
                    "name": "Amount",
                    "elements": [
                        {
                            "type": "text",
                            "text": "1.00"
                        }
                    ]
                },
                {
                    "type": "element",
                    "name": "Discount",
                    "elements": [
                        {
                            "type": "text",
                            "text": "0.00"
                        }
                    ]
                }
            ]
        }
    ]
}

Expected:

{
  "root": {
    "Amount": "1.00",
    "Discount": "0.00"
  }
}

Attempt-1: . This is not neat approach. So I do not like it.

var newJsonData = convertedXml2json
  .replace(/"elements": /g, "")
  .replace(/"type": "element",/g, "")
  .replace(/"name":/g, "")
  .replace(/"type": "text",/g, "")
  .replace(/"text":/g, "")
  .replace("[", "")
  .replace("{", "");
console.log(newJsonData);

Attempt-2: This comes as null

var len = convertedXml2json.elements,
    newData = {updatedJson:[]},
    i;

for ( i=0; i < len; i+=1 ) {
    newData.updatedJson.push(  [ convertedXml2json.elements[ i ].name, convertedXml2json.elements[ i ].elements[i].text] );
}
2
  • 2
    Please show what you've tried so far and explain what what went wrong with your current attempt (errors, unexpected results, etc.). Commented May 1, 2019 at 19:56
  • @p.s.w.g, I have updated question with my attempts. Commented May 1, 2019 at 20:15

1 Answer 1

3

Assuming you already have the JSON parsed into an object, you can use Array.prototype.map along with Object.fromEntries to convert the result back to an object:

const input = {
  "elements": [{
    "type": "element",
    "name": "root",
    "elements": [{
        "type": "element",
        "name": "Amount",
        "elements": [{
          "type": "text",
          "text": "1.00"
        }]
      },
      {
        "type": "element",
        "name": "Discount",
        "elements": [{
          "type": "text",
          "text": "0.00"
        }]
      }
    ]
  }]
};
const output = Object.fromEntries(input
  .elements.map(x => [x.name, Object.fromEntries(x
    .elements.map(y => [y.name, y.elements[0].text]))]));
console.log(output);

Alternatively, you could do this lodash's map and fromPairs:

// import _ from 'lodash'; 

const input = {
  "elements": [{
    "type": "element",
    "name": "root",
    "elements": [{
        "type": "element",
        "name": "Amount",
        "elements": [{
          "type": "text",
          "text": "1.00"
        }]
      },
      {
        "type": "element",
        "name": "Discount",
        "elements": [{
          "type": "text",
          "text": "0.00"
        }]
      }
    ]
  }]
};
const output = _.fromPairs(
  _.map(input.elements, x => [x.name, _.fromPairs(
    _.map(x.elements, y => [y.name, y.elements[0].text]))]));
console.log(output);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

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

3 Comments

I am getting TypeError: Object.fromEntries is not a function error. Do I need to install any npm for this?
@CSharper Hmm, it appears NodeJS doesn't support Object.fromEntries yet. You could use a polyfill like this. Otherwise, you could use a library like lodash, see my updated answer.
lodash option worked for me. I just had to install https://www.npmjs.com/package/lodash and this worked like a charm. Thank you.

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.