Show user where id is in friend array

I have trouble getting the user id from a friend list with arrays

friends collection

{
    "_id" : "2adDHy4sYrPaEjhyD",
    "friends" : [ 
        {
            "id1" : "Po8cXM2iBde6XeJa8",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 1
        }, 
        {
            "id1" : "4o8cXM2iBde6XeJa8",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 2
        }
    ]
}

Howto get the id1 where status is 2?

I have tried:

return Friends.find(
  {_id: Meteor.userId(),friends: 2 }
) 

and other but I’m doing something wrong when working with arrays

To get the user data

'yourUserId': function(){
       
    var friendsarray = this.friends[1].id1; 
    console.log(friendsarray);
    return Meteor.users.find({_id: friendsarray })},

I think you should reconsider how you’re modeling your relationships, but here’s the answer to your question:

const friend = Friends.findOne({
  _id: Meteor.userId(),
  'friends.status': 2
}, {
  fields: { 'friends.$': 1 }
});
const id1 = friend.friends[0].id1;

Edit: what does status represent anyhow?

1 Like

Why reinvent the wheel? https://atmospherejs.com/socialize/friendships

1 Like

status=

// friends.0.id1 = the invited friend
// friends.0.id2 = is the inviter
// friends.0.status = Status = 0 on your approve list, 1 waiting for someone to approve, 2 approved, 3 not approved list

What does this do:

  fields: { 'friends.$': 1 }

That returns only the matching document(s) within the array. Console.log that find with and without that fields argument to see what I mean.

I only get the first element with this:

db.getCollection('friends').find({"_id" : '2adDHy4sYrPaEjhyD' ,"friends.status":2},{"friends.status.$":1})

How to get all element where status is 2?

{
    "_id" : "2adDHy4sYrPaEjhyD",
    "friends" : [ 
        {
            "id1" : "4o8cXM2iBde6XeJa8",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 2
        }, 
        {
            "id1" : "Po8cXM2iBde6XeJa8",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 2
        }, 
        {
            "id1" : "2adDHy4sYrPaEjhyD",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 2
        }, 
        {
            "id1" : "2adDHy4sYrPaEjhyD",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 0
        }
    ]
}

@thorus in order to do that you need to work with the aggregation pipeline. Pretty straight forward:
https://docs.mongodb.com/manual/reference/operator/aggregation/filter/

Almost Perfect

but now I only need to show where field _id: 2adDHy4sYrPaEjhyD

How to place that in?


db.getCollection('friends').aggregate([

   {
      $project: {
          
         friends: {
            $filter: {
               input: "$friends",
               as: "friend",
               cond: { $eq: [ "$$friend.status", 2 ] }
               
            }
         }
      }
   }
]
   
   
   )

.aggregate([ {$match: { _id: 'XXX'}, { $project: { ... }} ]); It’s in their docs! Give it a read, aggregation pipeline is a super powerful tool.

1 Like

WORKS PERFECT:


db.getCollection('friends').aggregate([
{$match: { _id: '2adDHy4sYrPaEjhyD'}},
   {
      $project: {
          
         friends: {
            $filter: {
               input: "$friends",
               as: "friend",
               cond: { $eq: [ "$$friend.status", 2 ] }
               
            }
         }
      }
   }
]
1 Like

Do I need a packets like: meteorhacks:aggregate so it can work with meteor?

Have problemes with get it to work in my helper:

Template.networkyourUsers.helpers({

  yourUsers(){ return Friends.aggregate([
  {$match: { _id: '2adDHy4sYrPaEjhyD'}},
     {
        $project: {
            
           friends: {
              $filter: {
                 input: "$friends",
                 as: "friend",
                 cond: { $eq: [ "$$friend.status", 2 ] }
                 
              }
           }
        }
     }
  ]
  )};

js expected “,”

Aggregate only works on the server. And I don’t think you can create reactive publications with it either.

1 Like

I saw this package, but don’t know if it works as expected

@thorus you should take a look.

I would advice you do a Meteor.call() and fetch the data you need. Also, if you don’t have too many friends, you can just dump them all and do a client-side filtering :slight_smile:

However I would suggest changing the db model by abstracting it into a Friends collection, then all your problems are solved.

You can create reactive publications with that package. However, it has a dependency on an outdated meteorhacks package. I’ve recently released a more modern clone of the package, which uses import/export and ES6/7 code:

https://atmospherejs.com/tunguska/reactive-aggregate

2 Likes

I dont understand why it is so difficult to get a list of Ids from a array where status field is : 2

Is there no simple way? (dont have to be beautiful )

If you’re just asking about an Array, and not a Mongo collection, you can do this:

friends.filter(friend => friend.status == 2).map(friend => friend._id)

Sorry i’m still lost :neutral_face:

How to use that with:

main.js

Template.networkyourUsers.helpers({
yourUsers(){ return Friends.find({_id: Meteor.userId()} ); },


yourUserId(){ return CODE THAT USE THE yourUsers ARRAY id1 AND GET NAME FROM METEOR USERS DOCUMENT}
});

yourUsers result

{
    "_id" : "2adDHy4sYrPaEjhyD",
    "friends" : [ 
        {
            "id1" : "Po8cXM2iBde6XeJa8",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 1
        }, 
        {
            "id1" : "4o8cXM2iBde6XeJa8",
            "id2" : "2adDHy4sYrPaEjhyD",
            "status" : 2
        }
    ]
}

main.html

{{#each yourUsers}}

   {{#each yourUserId}}
      {{name}}
   {{/each}} 

{{/each}} 

This works:

JS

Template.networkyourUsers.helpers({
  isEqual: function (a, b) {
    return a === b;
  },
  yourUsers(){ return Friends.find(
    {_id: Meteor.userId()}
    )

  },

  'yourUserId': function(){
    
    
    var theuserId = this.id1; 
  
    return Meteor.users.find({_id: theuserId})},


});

html

{{#each yourUsers items}}

  {{#each friends}}

  
  {{#if isEqual status 2}}
  
  
  {{#each yourUserId }}
                    {{emails.[0].address}}
        
    {{/each}} 



{{/if}}
  

 
{{/each}}