Sruthish
Sruthish

Reputation: 53

Typescript array object filter

I'm trying to filter a array object in angular 5, this is my object

{
    "id_record": 2,
    "groupName": "PD",
    "count": 15,
    "userList": [{
            "name": "jeffhua",
            "nEmail": "[email protected]"
        },
        {
            "name": "joey",
            "nEmail": "[email protected]"
        },
        {
            "name": "angelagosto",
            "nEmail": "[email protected]"
        }
    ]
}

and here is my filter code

return items.filter(it => {
  return it.userList.filter(dit => {
    return dit.name.toLowerCase().includes(filterText)
  });
});

What could be wrong?

Upvotes: 0

Views: 2117

Answers (2)

faflo10
faflo10

Reputation: 386

In your filter code, the second filter returns an array :

return it.userList.filter(dit => {
    return dit.name.toLowerCase().includes(filterText)
  });
// returns array

and the filter method awaits a boolean to be returned. Try the following :

return items.filter(it => {
  return it.userList.filter(dit => {
    return dit.name.toLowerCase().includes(filterText);
  }).length !== 0;
});

In my code snippet, I check if the inner filter result (an array) is empty or not. If not, you return true to the parent filter, which will keep the current object in the resulting array.


Breakdown (edit)

The following returns a boolean, checking if the name in lowercase of one of your user contains filterText.

return dit.name.toLowerCase().includes(filterText);

Then, this block returns an array containing all the values that returned true in the condition explained before :

return it.userList.filter(dit => {
    return dit.name.toLowerCase().includes(filterText);
})

But, for the parent part of the code snippet to filter the array, it needs a boolean as return value :

return items.filter(it => {
  return // expect boolean
});

Then, the .length !== 0 at the end of :

it.userList.filter(dit => {
    return dit.name.toLowerCase().includes(filterText);
})

makes it a boolean which should be reflecting the condition you're wanting.

In full (and commented) :

// filter returns an array filtered by the method
return items.filter(it => {
  // awaits a boolean return value, with filter returning an array.
  return it.userList.filter(dit => {
    // filter awaits a boolean as return value AND returns a boolean --> ok for filter
    return dit.name.toLowerCase().includes(filterText);
  }).length !== 0; // filter has returned an array, we cast it to boolean while checking if its length is greater than 0.
});

Upvotes: 1

Ravi Theja
Ravi Theja

Reputation: 3401

Use some instead of inner filter

  return items.filter(it => {
      return it.userList.some(dit => {
        return dit.name.toLowerCase().includes(filterText)
      });
    });

Upvotes: 1

Related Questions