I’ learning meteor to write a simple app to pull information from one collection (a set of , and based on what is returned from that collection (a big list of items, names and item IDs), do a lookup in a different collection for an item name. My thinking was that the the item collection only be published on the server because it’s big and the clients don’t need direct access to it.
Everything more or less works, except I don’t think I’ve handled the callback correctly. Here is the simple test I wrote. The template where I pass the name of the item:
Template.operations.getTypeID = function(name) {
result = "";
console.log("Precall Logging name: ", name);
console.log("Precall Logging result: ", result);
result = Meteor.call('getID', name, function (error, result) {
console.log("Async Logging in call: result: ", result);
});
console.log("Name is now", name);
console.log("Result is now", result);
return name;
}
Here is the Method on the server where I’ll eventually look up the ID based on the name:
Meteor.methods({
getID: function(itemName) {
result = itemName + "_changed";
console.log("server: getID result:", result);
return result;
}
});
And here is where I call the template in the HTML file:
<td>{{getTypeID name}}</td>
When I’m using the app I can see that the Method getID is called in what looks like an asynch manner – the result in the getID method changes and is written to the console after the other entries in the template. How do I get set the result that is returned in the callback to be usable in the template and returned to the client so that I can render that in the page?
Update: Here is my console.log output after making some edits:
Precall Logging name: Apples lootlog.js:79
Precall Logging result: lootlog.js:80
Name is now Apples lootlog.js:86
Result is now undefined lootlog.js:87
Precall Logging name: Oranges lootlog.js:79
Precall Logging result: lootlog.js:80
Name is now Oranges lootlog.js:86
Result is now undefined lootlog.js:87
Precall Logging name: Melons lootlog.js:79
Precall Logging result: lootlog.js:80
Name is now Melons lootlog.js:86
Result is now undefined lootlog.js:87
Precall Logging name: Grapes lootlog.js:79
Precall Logging result: lootlog.js:80
Name is now Grapes lootlog.js:86
Result is now undefined lootlog.js:87
Precall Logging name: Onion lootlog.js:79
Precall Logging result: lootlog.js:80
Name is now Onion lootlog.js:86
Result is now undefined lootlog.js:87
Async Logging in call: result: Apples_changed lootlog.js:83
Async Logging in call: result: Oranges_changed lootlog.js:83
Async Logging in call: result: Melons_changed lootlog.js:83
Async Logging in call: result: Grapes_changed lootlog.js:83
Async Logging in call: result: Onion_changed
Here is what is printed to the meteor console:
server: getID Name: Apples
server: getID result: Apples_changed
server: getID Name: Oranges
server: getID result: Oranges_changed
server: getID Name: Melons
server: getID result: Melons_changed
server: getID Name: Grapes
server: getID result: Grapes_changed
server: getID Name: Onion
server: getID result: Onion_changed
I wouldn’t recommend the paradigm being used to transport data to the template, for each item being looped you’re making a Meteor.call to the server, which in a higher latency environment really slows things down.
The template helper has a Meteor.call inside which can’t run synchronously on the client side, so you have to pass the results to a reactive variable such as
Session, which in turn passes them to the template.I would recommend you make one call instead of many small ones, in the code below I’ve used one call with an array of names.
Server
Client
Again I’m not sure exactly what you want to do but you could replace the array with the data source of wherever you got the names from.
Session.set/get is reactive so as soon as Meteor gets the data from the server it will update the templates accordingly