0

Can't seem to return what I wanting. Eventually, I want to return an array of objects, or a single object that matches possibly two different partial key/value filters. In other words: const curQuery = {name:'Nex', tacTechnology: 'Dat'}

I'm planning on having multiple filters in the header of a table.

 const data = [{
            "id": "1",
            "name": "Unified Communications Portal",
            "tacTechnology": "Collaboration"
        }, {
            "id": "2",
            "name": "ACE Training Portal",
            "tacTechnology": "Networking Services"
        }, {
            "id": "3",
            "name": "Nexus 5K/2K Training Portal",
            "tacTechnology": "Data Center"
        }, {
            "id": "4",
            "name": "XR Training Portal",
            "tacTechnology": "Routing"
        }]

const curQuery = {name:'Nex'}

function setFilteredItems(curQuery) {
  const curQueryKeys = Object.keys(curQuery)
  const filteredItems = data.filter(
    (item) => {
      curQueryKeys.forEach((objKey) => {
        if (item[objKey] === undefined || curQuery[objKey] === null){
          console.log('its not', item[objKey], curQuery[objKey])
          return false;
        }
       else if(item[objKey].toLowerCase().includes(curQuery[objKey].toLowerCase())) {
         console.log('it includes', item[objKey], curQuery[objKey])
         return item;
         }
      })
    }
  )
  console.log('filteredItems', filteredItems )
}

setFilteredItems(curQuery);

Expecting filteredItems to be { "id": "3", "name": "Nexus 5K/2K Training Portal", "tacTechnology": "Data Center" }, but getting nothing back.

I created a quick codepen here: https://codepen.io/bmarker/pen/mddEdma

benishky
  • 901
  • 1
  • 11
  • 23

2 Answers2

1

The problem is that you're returning inside your forEach call, which just exits the function (something like continue). If you use a conventional for loop, your code works as you would expect because then the return is for the function you passed for filter:

const data = [{
  "id": "1",
  "name": "Unified Communications Portal",
  "tacTechnology": "Collaboration"
}, {
  "id": "2",
  "name": "ACE Training Portal",
  "tacTechnology": "Networking Services"
}, {
  "id": "3",
  "name": "Nexus 5K/2K Training Portal",
  "tacTechnology": "Data Center"
}, {
  "id": "4",
  "name": "XR Training Portal",
  "tacTechnology": "Routing"
}]

const curQuery = {
  name: 'Nex'
}

function setFilteredItems(curQuery) {
  const curQueryKeys = Object.keys(curQuery)
  const filteredItems = data.filter((item) => {
    for (const objKey of curQueryKeys) {
      if (item[objKey] === undefined || curQuery[objKey] === null) {
        console.log('its not', item[objKey], curQuery[objKey])
        return false;
      } else if (item[objKey].toLowerCase().includes(curQuery[objKey].toLowerCase())) {
        console.log('it includes', item[objKey], curQuery[objKey])
        return true;
      }
    }
  });
  console.log('filteredItems', filteredItems)
}

setFilteredItems(curQuery);
slider
  • 12,810
  • 1
  • 26
  • 42
0

You could get the key/values form the query object and iterate the entries by checking the object's value with the wanted value.

If you want not all properties of the query, you could replace Array#every with Array#some.

function getItems(query) {
    var entries = Object.entries(query).map(([k, v]) => [k, v.toLowerCase()]);
    return data.filter(o => entries.every(([k, v]) => o[k].toLowerCase().includes(v)));
}

const
    data = [{ id: "1", name: "Unified Communications Portal", tacTechnology: "Collaboration" }, { id: "2", name: "ACE Training Portal", tacTechnology: "Networking Services" }, { id: "3", name: "Nexus 5K/2K Training Portal", tacTechnology: "Data Center" }, { id: "4", name: "XR Training Portal", tacTechnology: "Routing" }];

console.log(getItems({ name: 'Nex' }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392