Reputation: 6019
The template helper .header
in this Meteor code is expected to re render the "updated" value of the property headerLabel
when the server method headerUpdate
runs but it is failing to show the newly updated value even though the collection has been updated with the new value.
What is the correct way to fix this? Thanks
Template.header.helpers({
headerLabel: function() {
var userId = Meteor.userId();
if (userId) {
Meteor.call('getHeaderLabel', userId, function(err, res) {
if (!err) {
Session.set('headerLabel', res);
}
});
return Session.get('headerLabel');
} else {
return 'Please login'
}
}
});
// on the client
Meteor.subscribe('headerLabelCol', Meteor.userId());
//on the server
Meteor.publish('headerLabelCol', function(userId) {
return HeaderLabelCol.find({userId: userId}, {limit: 1});
});
// Meteor methods
getHeaderLabel: function(userId) {
if (userId) {
var result = HeaderLabelCol.findOne({userId: userId});
if (result) { return result.headerLabel; }
}
}
headerUpdate: function(userId, headerLabel) {
HeaderLabelCol.update({userId: userId}, {$set: {headerLabel: headerLabel}});
}
edit
I changed the server size publish as below, using the reactive-publish package as below for no avail.
Meteor.publish('headerLabelCol', function (userId) {
this.autorun(function (computation) {
return HeaderLabelCol.find({userId: userId}, {limit: 1});
});
});
Upvotes: 0
Views: 91
Reputation: 2666
Solution 1 - using Pub/Sub
Publish headerLabelCol
on server
:
Meteor.publish('headerLabelCol', function() { return HeaderLabelCol.find({ userId: this.userId }, { limit: 1 }); });
Subscribe to headerLabelCol
on client
:
Meteor.subscribe('headerLabelCol');
In your Template.header.helpers
on client
:
Template.header.helpers({ headerLabel: function() { var userId = Meteor.userId(); if (userId) { var result = HeaderLabelCol.findOne({userId:userId}); if(result) { return result.headerLabel; } else { return 'Not Found'; } } else { return 'Please login'; } } });
Note: you can update the Collection
via Meteor.methods
or Collection.allow
.
Solution 2 - using Methods and Session
Your code works correctly when I tried it out. So I'm not sure what went wrong for you, here's how I would solve this problem:
Define the methods on both client
and server
.
In your Meteor.methods
on both client
and server
:
Meteor.methods({ getHeaderLabel: function(userId) { if (userId) { var result = HeaderLabelCol.findOne({ userId: userId }); if (result) { return result.headerLabel; } else { return null; } } }, headerUpdate: function(userId, headerLabel) { HeaderLabelCol.update({ userId: userId }, { $set: { headerLabel: headerLabel } }); } }
The Meteor.call
:
Meteor.call('getHeaderLabel', Meteor.userId(), function(err, res) { if (!err) { Session.set('headerLabel', res); } });
You can call the above from either the Template.header.helpers
(as you have done) or from within the Meteor.methods
headerUpdate
. Either will work, but I preferred to do it via headerUpdate
, like this:
headerUpdate: function(userId, headerLabel) { HeaderLabelCol.update({ userId: userId }, { $set: { headerLabel: headerLabel } }); Meteor.call('getHeaderLabel', userId, function(err, res) { if (!err) { Session.set('headerLabel', res); } }); }
This makes sure that the method is called every time the data is updated. So the Session
, which is a reactive
data source, is updated and the template helper is automatically called.
The Template helper:
Template.header.helpers({ headerLabel: function() { if (Meteor.userId()) { return Session.get('headerLabel'); } else { return 'Please login'; } } });
Initial call to getHeaderLabel
Meteor method:
Template.header.onCreated({ Meteor.call('getHeaderLabel', Meteor.userId(), function(err, res) { if (!err) { Session.set('headerLabel', res); } }); });
This will call the getHeaderLabel
method initially, before the DOM is rendered.
Upvotes: 1