问题
I would like create helpers for return string data :
className() {
let className;
Meteor.call('getIp', (err, res) => {
if (err) {
console.log(err);
} else {
// User ip
let ip = res.data.ip;
let userLikers = this.likers;
// Si l'utilisateur a déjà aimé le post
if (userLikers.includes(ip)) {
className = 'icon-favorite';
} else {
className = 'icon-favorite-border';
}
console.log(className);
return className;
}
});
}
My console.log(className) is good, and i don't understand why my return is empty.
Anyone have idea ?
Thank you !
回答1:
Meteor.call()
runs asynchronously on the client side. As with all asynchronous functions, they use a callback function. In your case that is the (err, res) => { ... }
part of the code.
This means that return className;
is the return value of the callback function. However, the code before or after the Meteor.call()
invocation uses another scope. So basically the classname()
function does not return anything, because there is no return statement for that function.
What you probably want is to assign the data from inside the callback to another variable that was declared before the callback invocation. E.g. something like
//Just for illustration.
//Do NOT use it, as it will not work an will not do what you might think it does.
className() {
let value;
Meteor.call('getIp', (err, res) => {
//do other stuff like error handling
// and getting the value here ...
console.log(className);
value = className;
});
return value;
}
However, that still does not account for the asynchronicity. It might very well be possible, that the function returns before the callback has fired. In that case you still get an empty return value. To avoid that, try to use Meteor.wrapAsync() to wrap the Meteor.call()
inside of it. This way you can get the return value of the asynchronous function call.
回答2:
The thing to remember here is that the server and client run in different places, one on the server and one in the browser. Meteor makes this difference less obvious, and makes it largely seamless to pass data around.
A technique I use is to get the server method to insert the result into a mongo collection. The helpers on the client will run automatically, and the client can display it when it arrives.
回答3:
As the other answers have pointed out, using Meteor Methods (or other asynchronous code) in a helper function (i.e., while rendering) is not going to work. Helpers cannot block, so cannot wait for the results from the server.
However looking at what you are trying to do, there are likely better solutions. Your client code is asking the Server for what it's (the client's) ip address is so you can select appropriate css classes.
I would suggest you look into Meteor's excellent Accounts package - it is very easy to work with, and will provide you with a robust way to identify users.
If you are wanting to provide this personalisation without requiring users to signin, I'd suggest you store a either a persistent id on the client (i.e. generate with random module, store in localStorage, or via persistent-session) or similar), or simply store on the client the list of items (posts?) that this user has liked.
This also avoids the fact that unless your users have static IP address, these will change often.
回答4:
You can try by using session. When template is loading, call your method and in callback assign return value to the session. In helper you can use that session to return valid data because in the beginning session will be undefined but when it is set in callback, helper will automatically rerun and session will return valid value. Hope this can help you with your problem :)
来源:https://stackoverflow.com/questions/40703704/meteor-helpers-return-nothing