Reputation: 573
I have the following made-up JavaScript array of objects:
const permissions = [
{
moduleEnabled: true,
moduleId: 1,
moduleName: 'Directory'
},
{
moduleEnabled: true,
moduleId: 2,
moduleName: 'Time off'
},
{
moduleEnabled: false,
moduleId: 3,
moduleName: 'Tasks'
},
{
moduleEnabled: false,
moduleId: 4,
moduleName: 'Documents'
}
]
I also have the following array of objects based on a collection of widgets that are available to be displayed:
const widgets = [
{
id: 1,
moduleId: 2,
title: 'Your time off'
},
{
id: 2,
moduleId: 1,
title: 'Your colleagues'
},
{
id: 3,
moduleId: 3,
title: 'Your tasks'
},
{
id: 4,
moduleId: 5,
title: 'Your sales pipeline'
},
{
id: 5,
moduleId: 4,
title: 'Your documents'
},
{
id: 6,
moduleId: 6,
title: 'Your legal cases'
}
]
What I'd like to do is to reduce the array of objects widgets
to a new array of objects filteredWidgets
based on the values in the permissions
array of objects, these being whether the moduleId
is found, and also where the moduleEnabled
is true
.
I've tried the code below, but it's not working:
const filteredWidgets = []
for (const permission in permissions) {
const found = widgets.filter((item) => item.moduleId === permission.moduleId && permission.moduleEnabled)
if (found) {
filteredWidgets.push(found)
}
}
console.log('filteredWidgets\n', filteredWidgets)
Any help will be greatly appreciated. Thanks in advance.
Edit: include expected output:
const filteredWidgets = [
{
id: 1,
moduleId: 2,
title: 'Your time off'
},
{
id: 2,
moduleId: 1,
title: 'Your colleagues'
}
]
Upvotes: 2
Views: 97
Reputation: 4241
I have a solution using reduce
But first, you have to create a Map and use that to create an Object with Object.fromEntries()
, and then finally use the reduce.
const permissions = [
{
moduleEnabled: true,
moduleId: 1,
moduleName: 'Directory'
},
{
moduleEnabled: true,
moduleId: 2,
moduleName: 'Time off'
},
{
moduleEnabled: false,
moduleId: 3,
moduleName: 'Tasks'
},
{
moduleEnabled: false,
moduleId: 4,
moduleName: 'Documents'
}
]
const widgets = [
{
id: 1,
moduleId: 2,
title: 'Your time off'
},
{
id: 2,
moduleId: 1,
title: 'Your colleagues'
},
{
id: 3,
moduleId: 3,
title: 'Your tasks'
},
{
id: 4,
moduleId: 5,
title: 'Your sales pipeline'
},
{
id: 5,
moduleId: 4,
title: 'Your documents'
},
{
id: 6,
moduleId: 6,
title: 'Your legal cases'
}
]
const permissonsMap = permissions.map((child,index) => {
return [child.moduleId, {...child}]
})
const permissionsObj = Object.fromEntries(permissonsMap);
//console.log(permissionsObj);
const filteredWidgets = widgets.reduce((aggArr,currItem) => {
if (permissionsObj[currItem.moduleId] && permissionsObj[currItem.moduleId].moduleEnabled){
aggArr.push(currItem);
}
return aggArr;
},[])
console.log(filteredWidgets);
Important lines are:
const permissonsMap = permissions.map((child,index) => {
return [child.moduleId, {...child}]
})
const permissionsObj = Object.fromEntries(permissonsMap);
//console.log(permissionsObj);
const filteredWidgets = widgets.reduce((aggArr,currItem) => {
if (permissionsObj[currItem.moduleId] && permissionsObj[currItem.moduleId].moduleEnabled){
aggArr.push(currItem);
}
return aggArr;
},[])
console.log(filteredWidgets);
Upvotes: 0
Reputation: 806
In your filter function, check for any permission which matches the given criteria:
const filteredWidgets = widgets.filter(widget =>
permissions.find(permission =>
(permission.moduleId === widget.moduleId) && permission.moduleEnabled));
Upvotes: 2
Reputation: 386520
You could take an object with the allowed ids and filter by moduleId
.
const
permissions = [{ moduleEnabled: true, moduleId: 1, moduleName: 'Directory' }, { moduleEnabled: true, moduleId: 2, moduleName: 'Time off' }, { moduleEnabled: false, moduleId: 3, moduleName: 'Tasks' }, { moduleEnabled: false, moduleId: 4, moduleName: 'Documents' }],
widgets = [{ id: 1, moduleId: 2, title: 'Your time off' }, { id: 2, moduleId: 1, title: 'Your colleagues' }, { id: 3, moduleId: 3, title: 'Your tasks' }, { id: 4, moduleId: 5, title: 'Your sales pipeline' }, { id: 5, moduleId: 4, title: 'Your documents' }, { id: 6, moduleId: 6, title: 'Your legal cases' }],
allowed = permissions.reduce((o, { moduleEnabled, moduleId }) =>
({ ...o, [moduleId]: moduleEnabled }), {}),
filteredWidgets = widgets.filter(({ moduleId }) => allowed[moduleId]);
console.log(filteredWidgets);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 15166
I think with .reduce()
and .find()
combination the following can work for you:
const permissions = [{moduleEnabled: true, moduleId: 1, moduleName: 'Directory' }, { moduleEnabled: true, moduleId: 2, moduleName: 'Time off' }, { moduleEnabled: false, moduleId: 3, moduleName: 'Tasks' }, { moduleEnabled: false, moduleId: 4, moduleName: 'Documents' }];
const widgets = [{ id: 1, moduleId: 2, title: 'Your time off' }, { id: 2, moduleId: 1, title: 'Your colleagues' }, { id: 3, moduleId: 3, title: 'Your tasks' }, { id: 4, moduleId: 5, title: 'Your sales pipeline' }, { id: 5, moduleId: 4, title: 'Your documents' },{ id: 6, moduleId: 6, title: 'Your legal cases'}]
const result = widgets.reduce((a, c) => {
const found = permissions.find(e => e.moduleId === c.moduleId)
return found && found.moduleEnabled ? a.concat(c) : a;
}, []);
console.log(result);
I hope this helps!
Upvotes: 1