dotNetkow dotNetkow -3 years ago 191
Javascript Question

JavaScript object array filtering with embedded array

I have an object that looks like the following:

let responseData = [
{
"name": "name",
"other": "value",
"anotherField": "blue",
"appRoles": [
{
"code": "roleOne",
"shouldDisplay": true
},
{
"code": "roleTwo",
"shouldDisplay": false
}
]
}


I need to maintain the original structure all while keeping existing properties. I only want to remove/filter out any "appRoles" where "shouldDisplay" is false.

The following works, using a forEach and a filter operation to create a new object array, but is it possible to condense this even more?

let filteredApps;
responseData.forEach((team) => {
let indyTeam = team;
indyTeam.appRoles = team.appRoles.filter((role) => role.shouldDisplay === true);
filteredApps.push(indyTeam);
});


When I use the map operation, I only get an array of the filtered appRoles - missing extra properties on each object such as "name":

let enabledAppRolesOnly =
responseData.map((team) =>
team.appRoles.filter((role) => role.shouldDisplay === true));

Answer Source

array.map function calls a callback for each element of your array, and then push the return value of it to a new array.

from MDN doc:

map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values, including undefined. It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).

So in your case, since you return team.appRoles.filter((role) => role.displayByDefault === true) which is your team array, you only get this.

What you could do would be this (in order to fully clone the object):

let responseData = [{
   "name": "name",
   "appRoles": [
     {
         "code": "roleOne",
         "shouldDisplay": true
     }, 
     {
         "code": "roleTwo",
         "shouldDisplay": false
     }
   ]
}]

let enabledAppRolesOnly = responseData.map(team => {
    const appRoles = team.appRoles.filter(role => role.shouldDisplay === true)
    return Object.assign({}, team, { appRoles })
});

console.log(enabledAppRolesOnly)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download