Home > Blockchain >  find key and replace value with it in javascript / node js
find key and replace value with it in javascript / node js

Time:02-20

let data = [{
    system: {
      id: "4gSSbjCFEorYXqrgDIP2FA",
      type: "Entry",
      name: "User"
    },
    DataDetails: {
      shortOption: {
        "en-us": "some value"
      },
      mediaFile: [{
          sys: {
            type: "Link",
            link: "Entry",
            id: "7kRzyt4PFo",
          },
        },
        {
          sys: {
            type: "Link",
            link: "Entry",
            id: "2OspeCtNK0s",
          },
        },
      ],
      mediaGalary: [{
          sys: {
            type: "Link",
            link: "Asset",
            id: "gHcw3Z1Ko",
          },
        },
        {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
      ],
        mediaExplore: [{
          sys: {
            type: "Link",
            link: "Asset",
            id: "euwcbds3282",
          },
        },
        {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "jndsiw23912",
          },
        },
      ],
      singleMediaImage: {
        sys: {
          type: "Link",
          linkType: "Asset",
          id: "7kRzyt4PFo",
        },
      },
    },
  },
  {
    system: {
      id: "1aBOO8tu3lUsjtICuIbUM5",
      type: "Entry",
      name: "User"
    },
    DataDetails: {
      short: {
        "en-us": "details of shorts"
      },
      shortSlugOption: {
        "hi-In": "options"
      },
      booleanField: {
        kl: "true"
      },
    },
  },
  {
    system: {
      id: "2pOUGnI1oRD7nsrYs600HA",
      type: "Entry",
      name: "Dummy"
    },
    DataDetails: {
      testingNewValue: [{
          sys: {
            type: "Link",
            link: "Entry",
            id: "66rzYr2BpWL",
          },
        },
        {
          sys: {
            type: "Link",
            link: "Entry",
            id: "1VTBHdLTdSW",
          },
        },
      ],
    },
  },
  {
    system: {
      id: "66rzYr2BpWL1VTBHdLTdSW",
      type: "Entry",
      name: "new"
    },
    DataDetails: {
      oneReference: {
        sys: {
          type: "Link",
          linkType: "Asset",
          id: "h2cPiuU9jIz",
        },
      },
      multiReference: [{
          sys: {
            type: "Link",
            link: "Asset",
            id: "gHcw3Z1Ko",
          },
        },
        {
          sys: {
            type: "Link",
            link: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
      ],
    },
  },
  {
    system: {
      id: "cIb5mqEBRWDD6hrNmFmFE",
      type: "Entry",
      name: "new"
    },
    DataDetails: {
      testingNewValue: {
        "hi-IN": "jksdsdo"
      }
    },
  },
  {
    system: {
      id: "7kRzyt4PFrX13gHcw3Z1Ko",
      type: "Entry",
      name: "Dummy"
    },
    DataDetails: {
      testingNewValue: {
        "en-us": "kknksdo"
      }
    },
  },
];

let anotherObj = {
  "gHcw3Z1Ko": {
    status: true,
    tag: [],
    filename: "exute-image.jpg",
    is_dir: false,
    parent_uid: null,
  },
  "h2cPiuU9jIz": {
    status: true,
    tag: [],
    filename: "wallpapers-6.jpg",
    is_dir: false,
    parent_uid: null,
  },
  "7kRzyt4PFo": {
    status: true,
    tag: [],
    filename: "in-space-rk.jpg",
    is_dir: false,
    parent_uid: null,
  },
  "euwcbds3282": {
    status: true,
    tag: [],
    filename: "justice-league.jpg",
    is_dir: false,
    parent_uid: null,
  },
  "jndsiw23912": {
    status: true,
    tag: [],
    filename: "batman.jpg",
    is_dir: false,
    parent_uid: null,
  },
};

let res = data.reduce((acc, curr) => {
  if (!acc[curr.system.name]) {
    acc[curr.system.name] = {};
  }

  let detailsObj = {};
  let assetArray=[];
  for (let key of Object.keys(curr.DataDetails)) {
    detailsObj[key] = Object.values(curr.DataDetails[key])[0];
    if (typeof Object.values(curr.DataDetails[key])[0] === "object") {
      Object.values(curr.DataDetails[key]).map((type) => {
        if (Array.isArray(type)) {
          type.map((link) => {
            if (link.sys.link === "Asset") {
              for (let id in anotherObj) {
                if (link.sys.id === id) {
                assetArray.push(anotherObj[id]);
                  detailsObj[key] = assetArray;
                }
              }
            }                
          });
        } else {
          if (type.sys !== undefined) {         
            // for single Asset
            if (type.sys.link === "Asset") {            
              for (let id in anotherObj) {
                if (type.sys.id === id) {  
                 detailsObj[key] = [anotherObj[id]];
                }
              }
            }
          }
        }
      });
    }
  }

  acc[curr.system.name][curr.system.id] = {
    title: curr.system.id,
    uid: curr.system.id,
    url: `/${curr.system.name}/${curr.system.id}`,
    ...detailsObj,
  };
  return acc;
}, {});

console.log(res);

I am trying to put two object data in one output but by reading the link which is Asset

but in the multiple Array list the output is displaying as single Asset output as mediaFile contain two entries but I don't know where I am doing wrong and it's displaying me a single value

as my main purpose is to replace the sys:{id:erfrdvsdf} by the anotherObj key data

so it should look like this for example my output is like this

"User": {
    "4gSSbjCFEorYXqrgDIP2FA": {
      "title": "4gSSbjCFEorYXqrgDIP2FA",
      "uid": "4gSSbjCFEorYXqrgDIP2FA",
      "url": "/User/4gSSbjCFEorYXqrgDIP2FA",
      "shortOption": "some value",
      "mediaFile": {
        "sys": {
          "type": "Link",
          "link": "Entry",
          "id": "7kRzyt4PFo"
        }
      },
      "mediaGalary": [
        {
          /**id:7**/
          "status": true,
          "tag": [],
          "filename": "in-space-rk.jpg",
          "is_dir": false,
          "parent_uid": null
        }
      ],
      "singleMediaImage": {
        "type": "Link",
        "linkType": "Asset",
        "id": "h2cPiuU9jIz"
      }
    },
  },

but it should like this

"User": {
    "4gSSbjCFEorYXqrgDIP2FA": {
      "title": "4gSSbjCFEorYXqrgDIP2FA",
      "uid": "4gSSbjCFEorYXqrgDIP2FA",
      "url": "/User/4gSSbjCFEorYXqrgDIP2FA",
      "shortOption": "some value",
      "mediaFile": {
        "sys": {
          "type": "Link",
          "link": "Entry",
          "id": "7kRzyt4PFo"
        }
      },
      "mediaGalary": [
        {
          "status": true,
          "tag": [],
          "filename": "in-space-rk.jpg",
          "is_dir": false,
          "parent_uid": null
        },
        {
          "status": true,
          "tag": [],
          "filename": "wallpapers-6.jpg",
          "is_dir": false,
          "parent_uid": null
        },
      ],
      "mediaExplore": [
        {
          "status": true,
          "tag": [],
          "filename": "justice-league",
          "is_dir": false,
          "parent_uid": null
        },
        {
          "status": true,
          "tag": [],
          "filename": "batman.jpg",
          "is_dir": false,
          "parent_uid": null
        },
      ],
      "singleMediaImage": [
        {
          "status": true,
          "tag": [],
          "filename": "wallpapers-6.jpg",
          "is_dir": false,
          "parent_uid": null
        },
      ]
    },
  },

but my expected output is what I am looking to it

Due to this I am stuck with the entry field as the same problem I am going through with entry field as I wrote same code to fetch the entry fields which are in Array and for the single entry field

where my code break I don't know

I know this is long code but help me out to solve this error as due to this I am not moving ahead

CodePudding user response:

You are missing some values because you don't check for linkType. Your loops are checking for sys.link but aren't checking for sys.linkType.

Use:

link.sys.link === 'Asset' || link.sys.linkType === 'Asset'

and

type.sys.link === 'Asset' || type.sys.linkType === 'Asset'

Also this line will override your array: detailsObj[key] = [anotherObj[id]];

Replace it with:

assetArray.push(anotherObj[id]);
detailsObj[key] = assetArray;

To be clear this code isn't good. A few suggestions:

  • Split your code in smaller logic units. Don't nest 5 levels of loops. Make functions that do small operations and name them accordingly (e.g. instead of doing for (let id in anotherObj) { ... }, put the logic inside a function named findAssetData)
  • Understand the difference between Array.prototype.forEach and Array.prototype.map (map usage in this code is wrong)
  • Use code quality tools like eslint, it will help if you are a beginner

CodePudding user response:

There's an error in your code: anotherObj has duplicate keys. If you log that out, you'll see that there are only two entries in that object:

let anotherObj = {
  gHcw3Z1Ko: {
    status: true,
    tag: [],
    filename: "exute-image.jpg",
    is_dir: false,
    parent_uid: null,
  },
  h2cPiuU9jIz: {
    status: true,
    tag: [],
    filename: "wallpapers-6.jpg",
    is_dir: false,
    parent_uid: null,
  },
  gHcw3Z1Ko: {
    status: true,
    tag: [],
    filename: "in-space-rk.jpg",
    is_dir: false,
    parent_uid: null,
  },
};

console.log(anotherObj)

Also, the mediaFile squashes the array of entries to one - you did not describe what you want to do with it, so I assumed that the first item from the array suffices.

But probably this is not what you are after (in the following snippet, I removed the first entry of the duplicate keys):

let data = [{
    system: {
      id: "4gSSbjCFEorYXqrgDIP2FA",
      type: "Entry",
      name: "User"
    },
    DataDetails: {
      shortOption: {
        "en-us": "some value"
      },
      mediaFile: [{
          sys: {
            type: "Link",
            link: "Entry",
            id: "7kRzyt4PFo",
          },
        },
        {
          sys: {
            type: "Link",
            link: "Entry",
            id: "2OspeCtNK0s",
          },
        },
      ],
      mediaGalary: [{
          sys: {
            type: "Link",
            link: "Asset",
            id: "gHcw3Z1Ko",
          },
        },
        {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
      ],
      singleMediaImage: {
        sys: {
          type: "Link",
          linkType: "Asset",
          id: "h2cPiuU9jIz",
        },
      },
    },
  },
  {
    system: {
      id: "1aBOO8tu3lUsjtICuIbUM5",
      type: "Entry",
      name: "User"
    },
    DataDetails: {
      short: {
        "en-us": "details of shorts"
      },
      shortSlugOption: {
        "hi-In": "options"
      },
      booleanField: {
        kl: "true"
      },
    },
  },
  {
    system: {
      id: "2pOUGnI1oRD7nsrYs600HA",
      type: "Entry",
      name: "Dummy"
    },
    DataDetails: {
      testingNewValue: [{
          sys: {
            type: "Link",
            link: "Entry",
            id: "66rzYr2BpWL",
          },
        },
        {
          sys: {
            type: "Link",
            link: "Entry",
            id: "1VTBHdLTdSW",
          },
        },
      ],
    },
  },
  {
    system: {
      id: "66rzYr2BpWL1VTBHdLTdSW",
      type: "Entry",
      name: "new"
    },
    DataDetails: {
      oneReference: {
        sys: {
          type: "Link",
          linkType: "Asset",
          id: "h2cPiuU9jIz",
        },
      },
      multiReference: [{
          sys: {
            type: "Link",
            link: "Asset",
            id: "gHcw3Z1Ko",
          },
        },
        {
          sys: {
            type: "Link",
            link: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
      ],
    },
  },
  {
    system: {
      id: "cIb5mqEBRWDD6hrNmFmFE",
      type: "Entry",
      name: "new"
    },
    DataDetails: {
      testingNewValue: {
        "hi-IN": "jksdsdo"
      }
    },
  },
  {
    system: {
      id: "7kRzyt4PFrX13gHcw3Z1Ko",
      type: "Entry",
      name: "Dummy"
    },
    DataDetails: {
      testingNewValue: {
        "en-us": "kknksdo"
      }
    },
  },
];

let anotherObj = {
  h2cPiuU9jIz: {
    status: true,
    tag: [],
    filename: "wallpapers-6.jpg",
    is_dir: false,
    parent_uid: null,
  },
  gHcw3Z1Ko: {
    status: true,
    tag: [],
    filename: "in-space-rk.jpg",
    is_dir: false,
    parent_uid: null,
  },
};

// this is the function that actually merges the source
// object with anotherObj
const mergeGallery = (src, other) => {
  return src.reduce((a, c) => {
    if (typeof a[c.sys.id] === "undefined") a[c.sys.id] = {}
    a[c.sys.id] = { ...other[c.sys.id] }
    return a
  }, {})
}

// just to display that the generation of conditional attributes
// can be extracted to their own functions
const getShortOption = (el) => {
  const shortOption = el.system.name === "User" && el.DataDetails && el.DataDetails.shortOption ? {
    shortOption: el.DataDetails.shortOption["en-us"]
  } : {}
  return shortOption
}

const getFormatted = (el, otherGallery) => {
  return {
    title: el.system.id,
    uid: el.system.id,
    url: `/${el.system.name}/${el.system.id}`,
    ...getShortOption(el),
    ...(el.DataDetails && el.DataDetails.mediaFile && {
      mediaFile: el.DataDetails.mediaFile[0]
    }),
    ...(el.DataDetails && el.DataDetails.mediaGalary && {
      mediaGalary: mergeGallery(el.DataDetails.mediaGalary, otherGallery)
    }),
    ...(el.DataDetails && el.DataDetails.singleMediaImage && {
      singleMediaImage: el.DataDetails.singleMediaImage.sys
    }),
  }
}

const categorizeItems = (data) => {
  return data.reduce((a, c) => {
    if (typeof a[c.system.name] === "undefined") a[c.system.name] = {}
    a[c.system.name][c.system.id] = getFormatted(c, anotherObj)
    return a
  }, {})
}

const ret = categorizeItems(data)

console.log(ret)

SUGGESTION

  1. The conditionals can be much shorter:
const getShortOption = (el) => {
  const shortOption =
    el.system.name === "User" && el.DataDetails && el.DataDetails.shortOption
      ? { shortOption: el.DataDetails.shortOption["en-us"], }
      : {};
  return shortOption;
};

// could be written as 
const getShortOption = (el) => {
  const shortOption = el.system.name === "User" && el.DataDetails?.shortOption?.["en-us"]
    ? { shortOption: el.DataDetails.shortOption["en-us"] }
    : {}
  return shortOption
}

If you use ?. chaining, all the conditinals are shorter - unfortunately SO snippets do not know about this syntax.

  1. Please, if you use English terms in your code, then correct the spelling of Galary to Gallery. It will be a nice source of confusion, if you don't.

CodePudding user response:

If you traverse complex objects manually, things will get complex very fast. And it'll be nightmare to maintain the code. There are good opensource libraries available to travers complex objects using simple queries. For example, JsonPath.
In following demo I've used JsonPath. It handles Asset as well as Entry without any special handling. For the demo I've provided replacements for all the ids.

let data = getData();
let anotherObj = getAnotherObj();

let res = data.reduce((acc, curr) => {
  if (!acc[curr.system.name]) {
    acc[curr.system.name] = {};
  }

  let detailsObj = {};
  Object.keys(curr.DataDetails).forEach(key => {
    let values = curr.DataDetails[key];

    // clone values to output
    detailsObj[key] = !Array.isArray(values) ? Object.assign({}, values) : [...values];

    // find and replace ids
    let ids = jsonpath.query(detailsObj[key], '$..id');
    ids.forEach((id, i) => {
      if (id in anotherObj) {
        if (Array.isArray(detailsObj[key]))
          detailsObj[key].splice(i, 1, anotherObj[id]);
        else
          detailsObj[key] = anotherObj[id];
      }
    });
  });

  acc[curr.system.name][curr.system.id] = {
    title: curr.system.id,
    uid: curr.system.id,
    url: `/${curr.system.name}/${curr.system.id}`,
    ...detailsObj,
  };
  return acc;
}, {});

document.body.insertAdjacentHTML('beforeend', `<pre>${JSON.stringify(res, undefined, 1)}</pre>`);
console.log(res);



function getData() {
  return [{
      system: {
        id: "4gSSbjCFEorYXqrgDIP2FA",
        type: "Entry",
        name: "User"
      },
      DataDetails: {
        shortOption: {
          "en-us": "some value"
        },
        mediaFile: [{
            sys: {
              type: "Link",
              link: "Entry",
              id: "7kRzyt4PFo",
            },
          },
          {
            sys: {
              type: "Link",
              link: "Entry",
              id: "2OspeCtNK0s",
            },
          },
        ],
        mediaGalary: [{
            sys: {
              type: "Link",
              link: "Asset",
              id: "gHcw3Z1Ko",
            },
          },
          {
            sys: {
              type: "Link",
              linkType: "Asset",
              id: "h2cPiuU9jIz",
            },
          },
        ],
        singleMediaImage: {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
      },
    },
    {
      system: {
        id: "1aBOO8tu3lUsjtICuIbUM5",
        type: "Entry",
        name: "User"
      },
      DataDetails: {
        short: {
          "en-us": "details of shorts"
        },
        shortSlugOption: {
          "hi-In": "options"
        },
        booleanField: {
          kl: "true"
        },
      },
    },
    {
      system: {
        id: "2pOUGnI1oRD7nsrYs600HA",
        type: "Entry",
        name: "Dummy"
      },
      DataDetails: {
        testingNewValue: [{
            sys: {
              type: "Link",
              link: "Entry",
              id: "66rzYr2BpWL",
            },
          },
          {
            sys: {
              type: "Link",
              link: "Entry",
              id: "1VTBHdLTdSW",
            },
          },
        ],
      },
    },
    {
      system: {
        id: "66rzYr2BpWL1VTBHdLTdSW",
        type: "Entry",
        name: "new"
      },
      DataDetails: {
        oneReference: {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
        multiReference: [{
            sys: {
              type: "Link",
              link: "Asset",
              id: "gHcw3Z1Ko",
            },
          },
          {
            sys: {
              type: "Link",
              link: "Asset",
              id: "h2cPiuU9jIz",
            },
          },
        ],
      },
    },
    {
      system: {
        id: "cIb5mqEBRWDD6hrNmFmFE",
        type: "Entry",
        name: "new"
      },
      DataDetails: {
        testingNewValue: {
          "hi-IN": "jksdsdo"
        }
      },
    },
    {
      system: {
        id: "7kRzyt4PFrX13gHcw3Z1Ko",
        type: "Entry",
        name: "Dummy"
      },
      DataDetails: {
        testingNewValue: {
          "en-us": "kknksdo"
        }
      },
    }
  ];
}


function getAnotherObj() {
  return {
    "h2cPiuU9jIz": {
      status: true,
      tag: [],
      filename: "wallpapers-6.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "gHcw3Z1Ko": {
      status: true,
      tag: [],
      filename: "in-space-rk.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "7kRzyt4PFo": {
      status: true,
      tag: [],
      filename: "mediaFile0.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "2OspeCtNK0s": {
      status: true,
      tag: [],
      filename: "mediaFile1.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "66rzYr2BpWL": {
      type: 'entry',
      tag: [],
      entry_details: "this is first entry ***",
      is_secret: false,
    },
    "1VTBHdLTdSW": {
      type: 'entry',
      tag: [],
      entry_details: "some other entry ***",
      is_secret: true,
    },
  };
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/jsonpath.min.js"></script>

Note, I haven't handled case "shortOption": "some value". Flattening single value objects is not in focus here anyway.



Or you can replace all the assets and entries in original object with single statement!

let data = getData();
let anotherObj = getAnotherObj();

jsonpath.apply(data, '$[*].DataDetails..[?(@.sys.id)]', e => anotherObj[e.sys.id]);

document.body.insertAdjacentHTML('beforeend', `<pre>${JSON.stringify(data, undefined, 1)}</pre>`);
console.log(data);



function getData() {
  return [{
      system: {
        id: "4gSSbjCFEorYXqrgDIP2FA",
        type: "Entry",
        name: "User"
      },
      DataDetails: {
        shortOption: {
          "en-us": "some value"
        },
        mediaFile: [{
            sys: {
              type: "Link",
              link: "Entry",
              id: "7kRzyt4PFo",
            },
          },
          {
            sys: {
              type: "Link",
              link: "Entry",
              id: "2OspeCtNK0s",
            },
          },
        ],
        mediaGalary: [{
            sys: {
              type: "Link",
              link: "Asset",
              id: "gHcw3Z1Ko",
            },
          },
          {
            sys: {
              type: "Link",
              linkType: "Asset",
              id: "h2cPiuU9jIz",
            },
          },
        ],
        singleMediaImage: {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
      },
    },
    {
      system: {
        id: "1aBOO8tu3lUsjtICuIbUM5",
        type: "Entry",
        name: "User"
      },
      DataDetails: {
        short: {
          "en-us": "details of shorts"
        },
        shortSlugOption: {
          "hi-In": "options"
        },
        booleanField: {
          kl: "true"
        },
      },
    },
    {
      system: {
        id: "2pOUGnI1oRD7nsrYs600HA",
        type: "Entry",
        name: "Dummy"
      },
      DataDetails: {
        testingNewValue: [{
            sys: {
              type: "Link",
              link: "Entry",
              id: "66rzYr2BpWL",
            },
          },
          {
            sys: {
              type: "Link",
              link: "Entry",
              id: "1VTBHdLTdSW",
            },
          },
        ],
      },
    },
    {
      system: {
        id: "66rzYr2BpWL1VTBHdLTdSW",
        type: "Entry",
        name: "new"
      },
      DataDetails: {
        oneReference: {
          sys: {
            type: "Link",
            linkType: "Asset",
            id: "h2cPiuU9jIz",
          },
        },
        multiReference: [{
            sys: {
              type: "Link",
              link: "Asset",
              id: "gHcw3Z1Ko",
            },
          },
          {
            sys: {
              type: "Link",
              link: "Asset",
              id: "h2cPiuU9jIz",
            },
          },
        ],
      },
    },
    {
      system: {
        id: "cIb5mqEBRWDD6hrNmFmFE",
        type: "Entry",
        name: "new"
      },
      DataDetails: {
        testingNewValue: {
          "hi-IN": "jksdsdo"
        }
      },
    },
    {
      system: {
        id: "7kRzyt4PFrX13gHcw3Z1Ko",
        type: "Entry",
        name: "Dummy"
      },
      DataDetails: {
        testingNewValue: {
          "en-us": "kknksdo"
        }
      },
    }
  ];
}


function getAnotherObj() {
  return {
    "h2cPiuU9jIz": {
      status: true,
      tag: [],
      filename: "wallpapers-6.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "gHcw3Z1Ko": {
      status: true,
      tag: [],
      filename: "in-space-rk.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "7kRzyt4PFo": {
      status: true,
      tag: [],
      filename: "mediaFile0.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "2OspeCtNK0s": {
      status: true,
      tag: [],
      filename: "mediaFile1.jpg",
      is_dir: false,
      parent_uid: null,
    },
    "66rzYr2BpWL": {
      type: 'entry',
      tag: [],
      entry_details: "this is first entry ****",
      is_secret: false,
    },
    "1VTBHdLTdSW": {
      type: 'entry',
      tag: [],
      entry_details: "some other entry ****",
      is_secret: true,
    },
  };
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/jsonpath.min.js"></script>

  • Related