I'm new to reselect and I've been having success with creating selectors so far until I tried to filter a list by a nested key value pair. Most of the options are strings or array of strings and they are working just fine, but I can't figure out how to filters this list by the true/false values in an object.
here is my working selector so far and the json I'm using it to sort
const getItemsVisibilityFilter = state => state.itemsVisibilityFilter
const getItems = state => state.items
export const getVisibleItems = createSelector(
[getItemsVisibilityFilter, getItems],
(itemsVisibilityFilter, items) => {
switch (itemsVisibilityFilter) {
case 'SHOW_ALL':
console.log(items)
return items
case 'SHOW_DAMAGE':
return items.filter(item => item.tags.includes('Damage'))
case 'SHOW_ATTACK_SPEED':
return items.filter(item => item.tags.includes('AttackSpeed'))
case 'SHOW_LIFE_STEAL':
return items.filter(item => item.tags.includes('LifeSteal'))
default:
return items
}
}
)
and this is a single item from the JSON
"1036": {
"stats": {
"FlatPhysicalDamageMod": 10
},
"description": "<stats>+10 Attack Damage</stats>",
"gold": {
"total": 350,
"sell": 245,
"base": 350,
"purchasable": true
},
"tags": [
"Damage",
"Lane"
],
"plaintext": "Slightly increases Attack Damage",
"image": {
"full": "1036.png",
"group": "item",
"sprite": "item0.png",
"h": 48,
"w": 48,
"y": 48,
"x": 48
},
"sanitizedDescription": "+10 Attack Damage",
"maps": {
"8": true,
"10": true,
"11": true,
"12": true,
"14": false,
"16": false,
"18": true,
"19": true
},
"into": [
"3077",
"3123",
"1053",
"3155",
"3134",
"3133",
"3034",
"3035",
"3044",
"3052",
"3072",
"3122",
"3144",
"3252"
],
"id": 1036,
"name": "Long Sword"
},
my question is how do I filter through the "maps" object and return the items that have a value of true? If this helps. what I would like to add to the original selector is 'SHOW_SUMMONERS_RIFT' - "maps": {11: true} like so
const getItemsVisibilityFilter = state => state.itemsVisibilityFilter
const getItems = state => state.items
export const getVisibleItems = createSelector(
[getItemsVisibilityFilter, getItems],
(itemsVisibilityFilter, items) => {
switch (itemsVisibilityFilter) {
case 'SHOW_ALL':
console.log(items)
return items
case 'SHOW_DAMAGE':
return items.filter(item => item.tags.includes('Damage'))
case 'SHOW_ATTACK_SPEED':
return items.filter(item => item.tags.includes('AttackSpeed'))
case 'SHOW_LIFE_STEAL':
return items.filter(item => item.tags.includes('LifeSteal'))
case 'SHOW_SUMMONERS_RIFT':
return items.filter(item => item.maps.includes(I don't know what or to put here to see if 11 === true))
default:
return items
}
}
)
If this isn't enough code to help provide a solution. please let me know and I can post anything you think would be more relevant. Or if there are docs somewhere I should be reading more... Everything I have found though is about updating nested objects and I can't find anything about comparing values. please and thank you
SOLUTION --- thanks to Hardik Modha for putting me on the right path. I don't know if this is the best solution or even a good way for using Reselect, Redux, or even plain javascript haha, but here is the case I came up with and it works for the selector based on a nested object
case 'SHOW_SUMMONERS_RIFT':
const riftItems = items.filter(item => {
const mapKey = Object.keys(item.maps)
const mapValue = Object.values(item.maps)
if (mapKey[2] && mapValue[2] === true) {
return item
}
return null
})
return riftItems
You just need to get all entries first using Object.keys
and then filter the entries which are having value true using filter
const filtered = Object.keys(map.maps).filter((item) => map.maps[item]);
const myObject = {
"1036": {
"maps": {
"8": true,
"10": true,
"11": true,
"12": true,
"14": false,
"16": false,
"18": true,
"19": true
},
},
"1037": {
"maps": {
"8": false,
"10": true,
"11": true,
"12": false,
"14": false,
"16": false,
"18": true,
"19": true
},
},
"1038": {
"maps": {
"8": true,
"10": false,
"11": true,
"12": true,
"14": false,
"16": false,
"18": false,
"19": true
},
},
}
Object.keys(myObject).forEach((key) => {
const maps = myObject[key].maps;
console.log(Object.keys(maps).filter(item => maps[item]));
});