1

im trying to get an array based on its element id of array of object and the structure is looks like this

{"data": [
        {
            "id": 46,
            "name": "shsjks",
            "desc": "ehejej",
            "code": "hshsbsb",
            "activation_type": 1,
            "detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",
        },
        {
            "id": 47,
            "name": "hhksns",
            "desc": "benemne",
            "code": "gevewk",
            "activation_type": 1,
            "detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"
        },
    ]}

im trying to get the data based on the detail id and what i did

let arr = a.data.filter(x => {
    return (JSON.parse(x.detail).filter(x => x.id === 419))
});
// returned all instead of first element of the array

i want it to returned

// filter where id 419
{
  "id": 47,
  "name": "shjks",
  "detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"
  ....
}
3
  • 4
    You probably want .length > 0 after the second filter, or replace it with .some Commented Apr 20, 2021 at 8:05
  • If you want the first element of the array, why do you call the result arr? It will not be an array, right? Commented Apr 20, 2021 at 8:11
  • Adam Smith - please see working answer below using .some Commented Apr 20, 2021 at 8:43

3 Answers 3

1

.filter will not perform a map. The return value of its callback function is supposed to just indicate whether the array element (from the top level array) should be included or not. So you should return a falsy value when you don't want an array to be included. As .some returns a boolean, that is a perfect candidate method to use for that purpose. And if you expect only one match, then .find is more appropriate than .filter:

let a = {"data": [{"id": 46,"name": "shsjks","desc": "ehejej","code": "hshsbsb","activation_type": 1,"detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",},{"id": 47,"name": "hhksns","desc": "benemne","code": "gevewk","activation_type": 1,"detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"},]}

let result = a.data.find(x => JSON.parse(x.detail).some(x => x.id === 419));

console.log(result);

If you want the details to remain parsed in the result, then first perform a map:

let a = {"data": [{"id": 46,"name": "shsjks","desc": "ehejej","code": "hshsbsb","activation_type": 1,"detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",},{"id": 47,"name": "hhksns","desc": "benemne","code": "gevewk","activation_type": 1,"detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"},]}

let result = a.data.map(x => ({ ...x, detail: JSON.parse(x.detail)}))
                   .find(x => x.detail.some(x => x.id === 419));

console.log(result);

If you are only interested in the id key itself, then perform a .flatMap to first collect all parsed detail arrays, so you get one array with all the details, and then .find the element you need:

let a = {"data": [{"id": 46,"name": "shsjks","desc": "ehejej","code": "hshsbsb","activation_type": 1,"detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",},{"id": 47,"name": "hhksns","desc": "benemne","code": "gevewk","activation_type": 1,"detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"},]}

let result = a.data.flatMap(x => JSON.parse(x.detail)).find(x => x.id === 419);

console.log(result);

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

2 Comments

alternatively you can use this: let arr = a.data.filter(x => JSON.parse(x.detail).filter(x => x.id === 419).length);
my bad, ill edit my question i want to returned it the whole array (id, name, desc, detail,...) but i get the gist of it thanks
0

You should do something like this.

let arr = a.data.filter(x => {
    return (JSON.parse(x.detail).filter(x => x.id === 419).length)
});

Array.filter returns [] if there is no value present. So when you return the array itself it is never considered as false.

Comments

0

The problem in your code is that the first filter need to return a boolean value (filter or not)

This will work for u:

const test = {
  data: [
    {
      id: 46,
      name: 'shsjks',
      desc: 'ehejej',
      code: 'hshsbsb',
      activation_type: 1,
      detail: '[{"id": 413, "name": "A"}, {"id": 416, "name": "B"}]',
    },
    {
      id: 47,
      name: 'hhksns',
      desc: 'benemne',
      code: 'gevewk',
      activation_type: 1,
      detail: '[{"id": 419, "name": "C"}, {"id": 423, "name": "D"}]',
    },
  ],
};

const arr = test.data.find((x) => JSON.parse(x.detail).some((d) => d.id === 419));

console.log(JSON.stringify(arr, null, 2));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.