Reputation: 2487
I've configured all users to be created with an empty favorites array: user.favorites: []
Since the users collection is treated differently, how should I publish, subscribe, and access subscribed favorites data in angular-meteor?
Here's what I have so far:
// Meteor.methods ==========================================
addFavorite: function(attendeeId){
var loggedInUser = Meteor.user();
if( !loggedInUser ){
throw new Meteor.Error("must be logged in");
}
loggedInUser.favorites.push(attendeeId);
loggedInUser.username = loggedInUser.username+"x";
console.log(loggedInUser.favorites);
}
// controller ========================================
$scope.addFavorite = function(attendeeId){
$meteor.call("addFavorite", attendeeId);
}
// server =======================================================
Meteor.publish('myFavorites', function(){
if(!this.userId) return null;
return Meteor.users.find(this.userId);
});
Meteor.users.allow({
insert: function(userId, doc){
return true;
},
update: function(useId, doc, fieldNames, modifier){
return true;
},
remove: function(userId, doc){
return true;
}
});
User.favorites is empty. When addFavorite is called, it logs an array with a single userId that doesn't update the mongoDB at all. It looks as if Meteor.user() isn't reactivly updating. Does anyone know what I'm doing wrong? Thank you!
EDIT
Latest iteration of code. Favorites are passed into $scope.favorites
but isn't reactive. How do I fix this? Thanks!
// publish
Meteor.publish('myFavorites', function(){
if(this.userId){
return Meteor.users.find(this.userId, {
fields: {
favorites: 1
}
});
}else{
this.ready();
}
});
// subscribe
$meteor.subscribe('myFavorites')
.then(function(subscriptionHandle)
{
var user = $meteor.collection(function(){
return Meteor.users.find({_id: Meteor.userId()});
});
$scope.favorites = user[0].favorites;
});
Upvotes: 2
Views: 816
Reputation: 913
Accounts collection is reactive, but by default only the username, emails, and profile fields are published. The quickest fix is to attach the favorites as a new field on the User.profile object.
// Meteor.methods ==========================================
addFavorite: function(attendeeId){
var loggedInUser = Meteor.user();
if( !loggedInUser ){
throw new Meteor.Error("must be logged in");
}
if (loggedInUser.profile.favorites){
loggedInUser.profile.favorites.push(attendeeId);
}
else {
loggedInUser.profile.favorites = [];
loggedInUser.profile.favorites.push(attendeeId);
}
loggedInUser.username = loggedInUser.username+"x";
console.log(loggedInUser.profile.favorites);
}
Although right now you probably are writing to the user, which you can verify by using meteor mongo
--> db.users.find().pretty()
, but the subscription does not publish your favorites field.
Alternatively, you can publish the favorites field
// Server code --------
Meteor.publish("userData", function () {
if (this.userId) {
return Meteor.users.find({_id: this.userId},
{fields: {'favorites': 1}});
} else {
this.ready();
}
});
I like to structure my users object around 3 properties:
Just make sure that when you remove the insecure
and autopublish
packages that you double-check your Collections security by using the Meteor.users.allow()
function in your server code
Run meteor list
to if you want to verify whether or not insecure
and autopublish
packages are being used in your current project. NOTE: By default Meteor does install them when you first create your app)
// Server code --------
Meteor.publish("userData", function () {
if (this.userId) {
return Meteor.users.find({_id: this.userId},
{fields: {'public': 1}});
} else {
this.ready();
}
});
Upvotes: 2