2

I have an array of objects. Filtering of array of object based on selection of a dropdown value.

const itemsList=[{
"id":"123",
"problems":{
    "causes":[ 
         {
        "SSEnabled": true,
        "IndusEnabled": false,
        "LogEnabled": true
        }
    ]
}
},
{
"id":"234",
"problems":{
    "causes":[
          {
        "SSEnabled": false,
        "IndusEnabled": false,
        "LogEnabled": true
        }
    ]
}
}]

we have a drop-down to filter SSEnabled cause. The options of drop-down are "show","nofilter","exclude".

Need to filter the list based on dropdown selection.

If "show" option of "SSEnabled" dropdown is selected, the list item where "SSEnabled":"true" should be the result.(i.e; id:"123")

If "exclude" of "SSEnabled" cause is selected, the list item where "SSEnabled:false" should be the result.(i.e; id:"234")

If "nofilter" is selected , it should ignore the filter. (i.e; id:"123", id:"234")

filterList(filterType, filterValue, itemsList) {
   // filterType : SSEnabled (type of dropdown changed)
   //filterValue : show, exclude , no filter
itemsList.map((items) => {
  if (
    items &&
    items.problems &&
    items.problems.causes &&
    items.problems.causes.length
  ) {
    items.problems.causes.filter((cause) => {
       if (cause[filterType] === true && filterValue === 'show') {
        return true;
      }
      if (cause[filterType] === false && filterValue === 'exclude') {
        return true;
      }
    });
  }
});

console.log(itemsList, 'filtered List');
}

But the list is not getting filtered. Please help in filtering.

3
  • 2
    use Array filter method Commented Dec 18, 2018 at 16:20
  • then inside your map method you are not returning anything Commented Dec 18, 2018 at 16:22
  • 1
    Array.map is the wrong tool. Array.map is for when you want an output array with as many elements as the input array. Commented Dec 18, 2018 at 16:25

1 Answer 1

2

A clean what to do this would be to define a lookup of functions that implement your logic and then pass the correct function to some() (or find()). You can pass it in field like show or exclude and the key you want to filter on like SSEnabled

const itemsList=[{"id":"123","problems":{"causes":[ {"SSEnabled": true,"IndusEnabled": false,"LogEnabled": true}]}},{"id":"234","problems":{"causes":[{"SSEnabled": false,"IndusEnabled": false,"LogEnabled": true}]}}]

// implement the selection logic based on keyword
// will return items where some of the cause match the condition
const filters = (field, key ) => {
    let options = {
     show:     (i) => i[key] == true,
     nofilter: (i) => true,
     exclude:  (i) => i[key] == false
    } 
    return options[field]
}

// filter using the above function:

let SSEnabled = itemsList.filter(item => item.problems.causes.some(filters('show', 'SSEnabled')) )
console.log(SSEnabled)

let SS_not_enabled = itemsList.filter(item => item.problems.causes.some(filters('exclude', 'SSEnabled')) )
console.log(SS_not_enabled)

let LogEnabled = itemsList.filter(item => item.problems.causes.some(filters('show', 'SSEnabled')) )
console.log(LogEnabled)

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

2 Comments

Can the SSEnabled in filters object be dynamic?? since I got more such attributes to filter like 'indusEnabled','logisticsEnabled'.
@user8599269, sure instead of a simple object lookup, make it a function that takes the attribute you are looking. See edit.

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.