On May 5, 2014, at 17:47, Folivi Fofo wrote:
> I'm working on an app where I need to display user's facebook events.
>
> The code below shows how to retrieve the users events and then perform a
> query to facebook api to retrieve more event details.
>
> As you can see, the process is: retrieving the events, then get more details
> about each, push all into an array then pass the array to the view.
>
> I fail in sending the array to the view and I believe it might have something
> to do with the asynchronous way of nodejs. Is this where the callback is
> needed?
>
> How can I solve this?
>
> Hope I'm clear.
>
> Thanks for your help
>
> index : function(req, res){
> graph.setAccessToken(req.user.token);
> var events = [];
> graph.get("/me/events?limit=500", {limit: 500}, function(err, rep) {
Here you are calling the graph.get function, and passing it a callback (the
function(err, rep) {...} function) and telling it you would like it to call
that function when it has finished getting the graph.
> for(key in rep["data"]){
> var query = "SELECT eid, name, creator, description, pic,
> pic_big, pic_cover, start_time, end_time FROM event WHERE eid=" +
> rep["data"][key].id;
> graph.fql(query, function(err, event_hash) {
And here, for each item returned from graph.get, you are calling graph.fql, and
again telling it to call a callback (function(err, event_hash) {...}) when it
is complete.
> var ev = event_hash["data"][0];
> if (ev.creator.toString() == req.user.uid.toString()) {
> events.push(ev);
> };
> })
> };
> });
> res.view({
> events: events
> });
Here you are responding with the view, right after having called graph.get,
which is before graph.get has completed, which is before you call graph.fql,
which is before graph.fql completes, which is before the callbacks have run,
which is before you have pushed things onto the events array. So your view is
rendered with an empty array.
You need to wait until all the callbacks have finished before calling res.view.
One way to do this is to keep a counter of how many tasks you need to complete,
and decrement it when each task finishes; when the counter reaches 0, you can
render the view.
index : function(req, res){
graph.setAccessToken(req.user.token);
var events = [];
graph.get("/me/events?limit=500", {limit: 500}, function(err, rep) {
var tasks = 0;
for(key in rep["data"]){
++tasks;
var query = "SELECT eid, name, creator, description, pic,
pic_big, pic_cover, start_time, end_time FROM event WHERE eid=" +
rep["data"][key].id;
graph.fql(query, function(err, event_hash) {
var ev = event_hash["data"][0];
if (ev.creator.toString() == req.user.uid.toString()) {
events.push(ev);
};
if (--tasks == 0) {
res.view({
events: events
});
}
})
};
});
},
However, the above assumes no error will ever occur, which is not likely. You
need to consider what should happen when an error occurs 1) from graph.get();
2) from any of the graph.fql() calls. Do you wish to call the view with an
error object instead of the events object? If so, then you need to write code
to do that, everywhere an error could occur (i.e. in every callback that's
given an err parameter).
There are libraries (npm modules) that can help you manage your control flow,
if you don't want to do it manually as described above. async is a popular one
but there are many others. Consider taking some hours to play with various
control flow libraries to see how they work and evaluate if any of them makes
enough sense to you to warrant using it in your project.
--
Job board: http://jobs.nodejs.org/
New group rules:
https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules:
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/nodejs/D70EC201-3360-44E0-ACB0-5AEBD41115BE%40ryandesign.com.
For more options, visit https://groups.google.com/d/optout.