javascript - Node.js AJAX route returns data before referenced function is evaluated -
update
got work, still think there's problem. correct return data if set settimeout timer long, 2000. if leave @ 200 callback function executes empty data because api call hasn't been returned yet.
i've updated code below.
setup:
i'm sending value front end via ajax (jquery) , using value call foursqaure api list of relevant venues back.
this working "fine" except order of events screwy. when insert value parameters function evaluate, i'm getting return value i'm not asking for, causes template render on front end before other return value function – 1 want – given.
and don't think it's being returned. logged console.
question:
how can return filtered list of json objects @ end of initgetvenues function in places.js via ajax front end?
context:
i'm using package connect foursquare: https://npmjs.org/package/foursquarevenues
ajax call on front end
$("#search-items").submit(function() { var placequery = $("#search-input").val(); $.ajax({ url: '/return/places/', data: {"passplacequery": placequery}, type: 'get', datatype: 'html', success: function(data) { $("#search-results-list").html(data); }, }); return false; });
index.js [updated]
returnplaces: function(req, res) { if (req.headers['x-requested-with'] === 'xmlhttprequest') { console.log("i've started routing"); return places.findvenue({ ll: "38.214986,-85.637054", radius: 32186, query: req.query.passplacequery, intent: "browse", categoryid: "4bf58dd8d48988d1e0931735" }, function(err, data) { console.log("venue callback"); if (err) { res.send(500); } console.log("attempting render: " + data); return res.render("place-results", { layout: false, foundplaces: data }); }); } else { return res.redirect("/"); } }
places.js [updated]
(function() { var foursquare, initgetvenues; foursquare = (require('foursquarevenues'))('secret', 'secret'); module.exports = { findvenue: initgetvenues = function(criteria, callback) { var jsonuniqueplaces; jsonuniqueplaces = []; foursquare.getvenues(criteria, function(error, venues) { var i, objuniqueplace, range, uniqueplaces, venuename; if (!error) { range = object.keys(venues.response.venues).length; uniqueplaces = []; = 0; while (i < range) { venuename = venues.response.venues[i].name; if (!(uniqueplaces.indexof(venuename) > -1)) { uniqueplaces.push(venuename); } i++; } = 0; while (i < uniqueplaces.length) { objuniqueplace = { place: uniqueplaces[i] }; jsonuniqueplaces.push(objuniqueplace); i++; } jsonuniqueplaces = json.stringify(jsonuniqueplaces); return jsonuniqueplaces; } }); return settimeout((function() { return callback(null, jsonuniqueplaces); }), 200); } }; }).call(this);
when settimeout 2000 get:
| i've started routing | [{"place":"quills coffee"},{"place":"quills coffe"},{"place":"quill's coffee"}] | venue callback | attempting render: [{"place":"quills coffee"},{"place":"quills coffe"},{"place":"quill's coffee"}] | /return/places/?passplacequery=quills 200 2009ms - 150
when settimeout 200 get:
| i've started routing | venue callback | attempting render: | /return/places/?passplacequery=quills 200 210ms - 11 | [{"place":"quills coffee"},{"place":"quills coffe"},{"place":"quill's coffee"}]
you can't return value inside findvenue
. call foursquare.getvenues
asynchronous. when node engine gets function call foursquare.getvenues(opt, callback)
starts operation , continues executing further statements, index.js continues executing, render response... time later, foursquare.getvenues
code invokes callback (presumably when it's done talking foursquare api.)
you need rewrite places.findvenue
take callback argument. when call places.findvenue()
pass function execute callback. that when you're supposed send response.
here simplified example can extend:
function findvenue(opt, callback){ settimeout(function(){ console.log('done foursquare.getvenues, calling routing function') callback(null, opt); // passs callback function settimeout. executes in 200ms // convention, pass null error object if successful } ,200); }; app.get('/return/places', function(req, res){ console.log('routing function start'); findvenue({ lat:40, lng: 70, query: 'foo' }, function(err, data){ console.log('findvenue callback'); if(err){ return res.send(500) }; res.render('template', {foo: data}); }); });
Comments
Post a Comment