thorus
November 8, 2017, 9:01pm
1
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
thorus
November 9, 2017, 11:05am
4
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.
thorus
November 10, 2017, 8:10am
6
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/
thorus
November 10, 2017, 9:04am
8
thorus:
n('f
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
thorus
November 10, 2017, 9:25am
10
diaconutheodor:
{$match: { _id: ‘XXX’}
WORKS PERFECT:
db.getCollection('friends').aggregate([
{$match: { _id: '2adDHy4sYrPaEjhyD'}},
{
$project: {
friends: {
$filter: {
input: "$friends",
as: "friend",
cond: { $eq: [ "$$friend.status", 2 ] }
}
}
}
}
]
1 Like
thorus
November 10, 2017, 9:36am
11
Do I need a packets like: meteorhacks:aggregate so it can work with meteor?
thorus
November 10, 2017, 9:41am
12
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 “,”
herteby
November 10, 2017, 10:43am
13
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
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
thorus
November 10, 2017, 1:14pm
16
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 )
herteby
November 10, 2017, 1:21pm
17
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)
thorus
November 10, 2017, 1:34pm
18
herteby:
filter
Sorry i’m still lost
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}}
thorus
November 10, 2017, 10:16pm
19
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}}