Returning value from callback within Meteor.method
asynchronous, callback, javascript, meteor, undefined
Solution
You need to use Future to achieve your goal.
How to use future since Meteor 0.6?
Meteor.startup(function () {
Future = Npm.require('fibers/future');
// use Future here
}
Your method rewritten with Future:
Meteor.methods({
'search': function(query) {
var future = new Future();
amazon.execute('ItemSearch', {
'SearchIndex': 'Books',
'Keywords': query,
'ResponseGroup': 'ItemAttributes'
}, function(results) {
console.log(results);
future["return"](results)
});
return future.wait();
}
});
Now it should work.
Meteor.call('search', 'harry potter', function(error, response) {
if(error){
console.log('ERROR :', error);
}else{
console.log('response:', response);
}
});
If you want to learn more about Future library I recommend watching screencast
Update on 26/12/2017
I just wanted to update this answer as you can achieve the same thing using promise and so, get rid of the "fibers" depedencies :)
An example is worth a thousand words
import scrap from 'scrap';
Meteor.methods({
'hof.add'(el) {
check(el, {
_link: String
});
const promise = getHofInfo(el._link)
.then((inserter) => {
inserter.owner = Meteor.userId();
Hof.insert(inserter);
return true;
})
.catch((e) => {
throw new Meteor.Error('500', e.message);
});
return promise.await();
}
});
function getHofInfo(_link) {
return new Promise((resolve, reject) => {
scrap(_link, function (err, $) {
if (err) {
reject(err);
} else {
const attakers = $('#report-attackers').find('li').text();
const defender = $('#report-defenders').find('li').text();
const _name = attakers + ' vs ' + defender;
const _date = new Date();
resolve({ _name, _date, _link });
}
});
});
}
Problem
I am running into something I don't understand with Meteor. I have this method, which takes a query, sends it to amazon, and then in the callback of that function I try to return the results. ``` Meteor.methods({ 'search': function(query) { var bookInfo; if (Meteor.isServer) { amazon.execute('ItemSearch', { 'SearchIndex': 'Books', 'Keywords': query, 'ResponseGroup': 'ItemAttributes' }, function(results) { bookInfo = results; console.log(bookInfo); return bookInfo; }); } } }); ``` But when I put the following into the console in my browser (chrome): ``` Meteor.call('search', 'harry potter', function(error, response) { console.log('response:', response); }); ``` I get the this: ``` undefined response: undefined VM13464:3 ``` I think I understand that the first undefined comes from the method not returning anything on the client, but the callback doesn't seem to work at all. The amazon.execute(...) is definitely returning something, as the console.log right above the return does log the info I'm looking for. Any ideas what's going wrong and how I can fix it?