Sunday, 1 October 2017

javascript - Callback in Node.js and Database variable




I don't understand callbacks in nodejs.




I need to get a podcast number from the database and use it in my code



I get right now from console.log



[Function: index]


Is there any solution in node.js to get variable from a database and reuse it later in the code?



var index = function( callback ) {   

var podcast = 0;
User.findOne({ sessionID: this.event.session.sessionId }, function(err, user) {
if (err ||!user){

}
else {
console.log(user);
podcast = user.podcast;
}
});

callback( podcast );
};

index();

var callback = function(data) {
return data;
}

var iUseMyAnywhere = callback;


Answer




It look like it is impossible what I want to do in Node.js




It's completely possible. Only, you need to use asynchronous API's, which makes it ankward.




Is there any solution in node.js to get variable from a database and reuse it later in the code?





Not exactly. When you connect to a database -or, by the way, do anything asynchronously, like fetching something over http or reading from disc- you can't assign that thing right over:



var myUserFromDb = User.find('john doe', function(err, res){...}); //this will fail 


Because that function you're passing as the second parameter will execute sometime in the future. User.find() itself doesn't return the user.



So, sadly, you can't just get the user in the user var and pass it to another module -let's say a podcast module-.




However, let's say you have a 'user.js' module, with exposes a withUser method than aks the database for a user and then calls a provided function with the user, when the db call is resolved.



And let's say you have a 'podcast.js' file/module with a getPodcast method that needs a user.



getPodcast can't just ask 'user.js' a user. However, it can ask for a function that will run with the user passed as parameter:



User.js



function withUser(callback){

User.find({_id: 1}, (err, user)=> {
callback(user);
})
}


podcast.js



function getPodcast(){


withUser( function(user){
//now we really have the user inside podcast.js, and we can work with it.
//Sadly, that will surely involve more asynchronous api's, which is painful.
})
}


Now getPodcast will have access to the user inside its parameter callback.





Is there any easier method rather than callback?




Yes, you should read about promises. When using promises, things are -a little less- painful. A promise api would work as:



User.js



function getUser(id){
//let's say we return a promise that wraps the `User.find` database request
}



podcast.js



getUser(userId).then(user => getPodcast(user)).then(podcastResult => ...)


This don't see really better. However, when you are working with promise api's, you can then start using async/await.



podcast.js




 async function getPodcast(userId){
const user = await User.getUser(uesrId);
const otherAsyncThing = await ...someAsyncApiCall;

doAnythingWithUser(user); //this line won't execute until user is resolved, even if there aren't callbacks involved :-D
}


A final, unasked word of advice: when working with node.js, be sure you understand how callback api's and async things really work before writing a ton of code. Otherwise, you'll get really coupled and brittled code, where objects get passed through mountains of callbacks and code is unreadable and undebuggable :-D



No comments:

Post a Comment

casting - Why wasn't Tobey Maguire in The Amazing Spider-Man? - Movies & TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...