1

I'm accessing a JSON that comes back looking like this:

[
{
    "itemType": "SelectionTitle",
    "name": "1105F.MID",
    "active": true,
    "isFactoryDefault": false,
    "factoryCode": "",
    "seasons": [],
    "denominations": [],
    "groups": [],
    "length": 0,
    "_id": "5ada2217c114ca048e1db9b0",
    "created_by": "5ab57289d8d00507b29a3fdd",
    "selectionFile": {
        "itemType": "SelectionFile",
        "name": "1105F.MID",
        "active": true,
        "isFactoryDefault": false,
        "selectionType": "Music",
        "sfzFile": "",
        "destination": "/data/uploads",
        "encoding": "7bit",
        "fieldname": "file",
        "filename": "782f49a7cd72b865b4e2d286816792e7",

...
        "found": true,
        "flError": false,
        "error_strings": [],
        "_id": "5ada2217c114ca048e1db9af",
        "created_by": "5ab57289d8d00507b29a3fdd",
        "slug": "1105fmid",
        "__v": 0,
        "createdAt": "2018-04-20T17:23:35.216Z",
        "updatedAt": "2018-04-20T17:23:35.788Z",
        "selectionTitles": null,
        "id": "5ada2217c114ca048e1db9af"
    },
    "slug": "1105fmid",
    "createdAt": "2018-04-20T17:23:35.285Z",
    "updatedAt": "2018-04-20T17:23:35.285Z",
    "__v": 0,
    "id": "5ada2217c114ca048e1db9b0"
}, ...

The react-select node module that I am using takes the key "label" to generate a populated dropdown.

The JSON is coming from the web so I can't control how the JSON is setup. How do I parse the JSON to find all the instances of "name" and replace that key with "label" ?

For example "name" : 1105F.MID" should be changed to "label" : "1105.MID"

Would it be inefficient to convert the entire thing to a string and use the javascript method find/replace?

johnsonjp34
  • 3,139
  • 5
  • 22
  • 48
  • so it is `name` anywhere? – epascarello Oct 26 '18 at 18:40
  • Never use string operations on JSON. JSON properties are already Javascript objects. – js1568 Oct 26 '18 at 18:43
  • Check this out (I like the lodash answer better than the chosen answer): https://stackoverflow.com/questions/8747561/is-there-any-way-to-rename-js-object-keys-using-underscore-js – JoeKincognito Oct 26 '18 at 18:43
  • @js1568 JSON has no properties JSON is a string (well, so it has properties of a string but not object properties of the content of the JSON) JSON is a string that must be parsed to become a JavaScript object in that sense. – Mark Schultheiss Oct 26 '18 at 21:00

3 Answers3

2

Assuming your JSON array is stored in the variable data:

data.forEach(item => item.label = item.name)

This would be sufficient to duplicate the name property as the label property for each item in the array.

js1568
  • 7,012
  • 2
  • 27
  • 47
  • Hi js1568, curious to know how this will update nested objects like mentioned in OP, inside "selectedFile" sub object. Thnx – Nitish Narang Oct 26 '18 at 19:14
  • This only updates the outermost object, not nested objects. – js1568 Oct 26 '18 at 19:20
  • Though not directly asked in OP, 'name' property also exists in sub objects as you can see in OP. So, I thought updating nested props would also be required. Anyways thnx – Nitish Narang Oct 26 '18 at 19:24
1

I have created a function replace() to deal with every object and nested objects, which will add property 'label' if 'name' property is found. Pls see if it's useful to you.

var arr = [
{
    "itemType": "SelectionTitle",
    "name": "1105F.MID",
    "active": true,
    "isFactoryDefault": false,
    "factoryCode": "",
    "seasons": [],
    "denominations": [],
    "groups": [],
    "length": 0,
    "_id": "5ada2217c114ca048e1db9b0",
    "created_by": "5ab57289d8d00507b29a3fdd",
    "selectionFile": {
        "itemType": "SelectionFile",
        "name": "1105F.MID"
    }
},
{
    "itemType": "SelectionTitle",
    "name": "test",
    "active": true,
    "isFactoryDefault": false,
    "factoryCode": "",
    "seasons": [],
    "denominations": [],
    "groups": [],
    "length": 0,
    "_id": "5ada2217c114ca048e1db9b0",
    "created_by": "5ab57289d8d00507b29a3fdd",
    "selectionFile": {
        "itemType": "SelectionFile",
        "name": "testing"
    }
}
]

// this method will take care of adding new property
function replace(obj, from, to) {
 Object.entries(obj).forEach(([key, value]) => (
     key == from && (obj[to] = obj[from])
     , typeof value === "object" && replace(value, from, to)
 ))
}

arr.forEach(d => replace(d, 'name', 'label'))

// you can check this log for property 'label' whereever 'name' exists
console.log(arr)
Nitish Narang
  • 4,124
  • 2
  • 15
  • 22
0

Relying on the structure of server response is bad; especially when you say you have not control over it. A better way would be to always parse the server response, construct whatever necessary for the react-select component to work and pass that only.

muratgu
  • 7,241
  • 3
  • 24
  • 26