2

I am working with graphql returned data that looks like this:

"userRelations": [
    {
      "relatedUser": {
        "id": 4,
        "firstName": "Jack",
        "lastName": "Miller"
      },
      "type": "FRIEND"
    },
    {
      "relatedUser": {
        "id": 3,
        "firstName": "Rhena",
        "lastName": "Tahoma"
      },
      "type": "CONTACT"
    }
  ]

I had to separate all those items which had the type: "FRIENDS". I did this and it worked perfectly:

    var friendArray = new Array();
    for (let i in data.users.nodes[0].userRelations) { 
    if (data.users.nodes[0].userRelations[i].type == "FRIEND")
    {
        friendArray.push(data.users.nodes[0].userRelations[i]);
    }
  }

However, I read that using for loops and for in is not a good idea. Is there any other way to iterate and check all the objects without for loops? I tried using this but it doesn't give the correct results:

data.users.nodes[0].userRelations.forEach((object: Object)=> {
    if (data.users.nodes[0].userRelations.type == "FRIEND")
    {
        friendArray.push(data.users.nodes[0].userRelations.object);
    }
})  

The friendsArray remains empty. What am I missing out?

Edit: After filtering the friends data, I want to render some items by mapping. I was trying to do something like this:

data.users.nodes[0].userRelations.map()
data.users.nodes[0].userRelations.filter(({ type }) => type === 'FRIEND').map(/*code*/)

but this gave me an error that:

Binding element 'type' implicitly has an 'any' type.ts(7031)
  • 1
    Have a look at array.filter(), you can do `const friends = data.users.nodes[0].userRelations.filter(userRelation => userRelation.type === 'FRIEND")` – andy mccullough Jun 10 '20 at 22:07
  • Does this answer your question? [For-each over an array in JavaScript](https://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript) – Michael Freidgeim Nov 24 '21 at 00:17

4 Answers4

1

In your case I would use filter:

var result = data.users.nodes[0].userRelations.filter(element=>element.type=="FRIEND");
SomoKRoceS
  • 2,934
  • 2
  • 19
  • 30
  • This gives me ```This condition will always return 'false' since the types 'boolean' and 'string' have no overlap.ts(2367)``` in typescript. –  Jun 10 '20 at 22:10
  • You’ve got a typo `=>` not `->` – Ibraheem Jun 10 '20 at 22:14
  • Still, this gives me ```Parameter 'element' implicitly has an 'any' type.```If I infer parameters from usage, it changes to ```element: { type: string; }```. Originally, the type is ```UserRelation```that I have defined myself. However, that doesn't work either. –  Jun 10 '20 at 22:22
  • ```((element: { type: UserRelation; }) => element.type=="FRIEND");```gives me the same error as in my first comment –  Jun 10 '20 at 22:22
  • What about `var result = data.users.nodes[0].userRelations.filter((element: UserRelation)=>element.type==="FRIEND");` ? – SomoKRoceS Jun 10 '20 at 22:24
0
data.users.nodes[0].userRelations.forEach((o: Object)=> {
    if (o.type == "FRIEND")
    {
        friendArray.push(o);
    }
})  
Ibraheem
  • 2,168
  • 20
  • 27
0

First of all, using a for loop there is fine.

If you want to use foreach, you'll need to use the object element you create in the forEach callback. That's the advantage of using foreach.

data.users.nodes[0].userRelations.forEach((object: Object)=> {
    if (object.type == "FRIEND")
    {
        friendArray.push(object);
    }
})  

If you want to improve the function, you may want to use a .filter, which is probably the cleanest way of solving this.

Sam Broner
  • 471
  • 2
  • 9
0

Have a look at array.filter(), you can do const friends = data.users.nodes[0].userRelations.filter(userRelation => userRelation.type === 'FRIEND") but to your current code, you could change your if statement to be - if(object.type==='FRIEND')

andy mccullough
  • 9,070
  • 6
  • 32
  • 55