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

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.