0

I have properties in an Array and an Object. I need to remove the properties, which are not in the Array allowedFields.

Actually, I need to create separate Object with only allowed fields from response data. Please suggest a solution.

let allowedFields = [
  "organization_id",
  "organization_name",
  "payload.offer.application_id",
  "payload.offer.user_id",
  "id",
  "candidate_id",
];

Below is the Object values:

let data = {
  organization_id: 4002400004,
  organization_name: "Velocity Global Integration Sandbox",
  action: "offer_updated",
  payload: {
    offer: {
      id: 4524843004,
      application_id: 31948577004,
      user_id: 4123647004,
      version: 1,
      sent_on: null,
      resolved_at: "2022-05-19T06:21:25.084Z",
      start_date: "2022-05-17",
      notes: null,
      job_id: 4298940004,
      offer_status: "Accepted",
    },
    resume: {
      name: "manikandan",
    },
  },
};

Object only have the properties which exists in the allowedFields Array. Expecting output below:

let output = {
  organization_id: 4002400004,
  organization_name: "Velocity Global Integration Sandbox",
  payload: {
    offer: {
      application_id: 31948577004,
      user_id: 4123647004,
    },
  },
};
4
  • 1
    Use JSON.stringify and JSON.parse with a reviver that checks your whitelist Commented May 27, 2022 at 9:15
  • Shouldn't there be an id in your expected output? It's in the allowedFields but seems to have been removed? Commented May 27, 2022 at 9:18
  • @DBS some typing mistake, now i have edited. actually its should allow payload.offer.application and payload.offer.user_id only in offer object Commented May 27, 2022 at 9:22
  • If you are okay using lodash, you can use the _.pick method to get only the required properties. See this link for further info. Commented May 27, 2022 at 9:49

2 Answers 2

4

Approach 1

  1. Loop over all the paths in the allowedPaths array.

  2. Split the path by . to obtain an array of keys.

  3. Then loop over the array of keys and for every key fill in the resData object using actual data object.

const 
  allowedPaths = ["organization_id","organization_name","payload.offer.application_id","payload.offer.user_id","id","candidate_id"],
  data = {organization_id:4002400004,organization_name:"Velocity Global Integration Sandbox",action:"offer_updated",payload:{offer:{id:4524843004,application_id:31948577004,user_id:4123647004,version:1,sent_on:null,resolved_at:"2022-05-19T06:21:25.084Z",start_date:"2022-05-17",notes:null,job_id:4298940004,offer_status:"Accepted"},resume:{name:"manikandan"}}};

function filterData(data, allowedPaths) {
  const resData = {};
  allowedPaths.forEach((path) => {
    const pathArr = path.split(".");
    let actualDataObj = data;
    let resultantObj = resData;
    let toDetach;
    for (let i = 0; i < pathArr.length; i++) {
      const k = pathArr[i];
      if (!actualDataObj?.hasOwnProperty(k)) {
        if (toDetach) {
          delete toDetach.object[toDetach.key];
        }
        return;
      }
      if (i === pathArr.length - 1) {
        resultantObj[k] = actualDataObj[k];
      } else if (!resultantObj.hasOwnProperty(k)) {
        resultantObj[k] = {};
        if (!toDetach) {
          toDetach = { object: resultantObj, key: k };
        }
      }
      resultantObj = resultantObj[k];
      actualDataObj = actualDataObj[k];
    }
  });
  return resData;
}

console.log(filterData(data, allowedPaths));

Approach 2

You can also recursively loop over all the properties in the data object and create an object with the allowed properties.

const 
  allowedPaths = ["organization_id","organization_name","payload.offer.application_id","payload.offer.user_id","id","candidate_id"],
  data = {organization_id:4002400004,organization_name:"Velocity Global Integration Sandbox",action:"offer_updated",payload:{offer:{id:4524843004,application_id:31948577004,user_id:4123647004,version:1,sent_on:null,resolved_at:"2022-05-19T06:21:25.084Z",start_date:"2022-05-17",notes:null,job_id:4298940004,offer_status:"Accepted"},resume:{name:"manikandan"}}};

function filterData(data, allowedPaths, parentPath = "") {
  return Object.entries(data).reduce((o, [k, v]) => {
    const path = `${parentPath ? parentPath + "." : ""}${k}`;
    if (allowedPaths.has(path)) {
      return { ...o, [k]: v };
    }
    if (v && typeof v === "object") {
      const subObj = filterData(v, allowedPaths, path);
      if (Object.keys(subObj).length) {
        return { ...o, [k]: subObj };
      }
    }
    return o;
  }, {});
}

console.log(filterData(data, new Set(allowedPaths)));

Note: Both the above solutions also handle scenarios where invalid paths are present in the allowedPaths array. Here are some invalid paths:

  • "id"
  • "payload.offer.application_id.value"
  • "foo.bar.baz"

Relevant documentations:

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

1 Comment

great... its working fine...
0

Can you try this.

function CheckKey(obj, keyVal, allowedFields) {
    Object.keys(obj).forEach(function (key) {
        let keyValInternal = keyVal.length === 0 ? key : keyVal + '.' + key;

        if (typeof obj[key] === 'object') {
              return CheckKey(obj[key], keyValInternal, allowedFields);
        } else {
          if (allowedFields.indexOf(keyValInternal) < 0){
              delete obj[key];
          }  
        }
    });
}

I ran this on a simple set of data (example below) and it stripped out the "b" parameter

let x = {t: {a:1, b:2}, s: 3}

let allowedFields = [
  "t.a"
];

CheckKey(x, '', allowedFields);

console.log(x)

Output

{
    "t": {
        "a": 1
    }
}

2 Comments

i couldnt console the response, in the CheckKey function value is not returned
Modified it as I posted my answer when the original requirement didn't have the nested conditions in there. But it should work now with your original list.

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.