Node.js won't return anything? [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
why wont usernametoid function return anything? i know it exist by consoling it out, but it wont store in the otherplayerid variable? why?
my app: ( calling post api kill)
var userFunc = require('../factory/user_factory.js');
app.post('/api/kill', function (req, res) {
var username = "signature";//req.query.username;
var otherplayerid = userFunc.usernametoid(username);
if (!(otherplayerid)) {
console.log("other player is acually " + otherplayerid);
result.push("denne brukeren finnes ikke! " + otherplayerid);
} else {
}
});
and my user_factory:
var articles = require('../controllers/articles.server.controller'),
path = require('path'),
mongoose = require('mongoose'),
Article = mongoose.model('Article'),
Users = mongoose.model('User'),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller'));
exports.usernametoid = usernametoid;
function usernametoid(id) {
var query = Users.findOne( { username : id } );
query.exec(function(err, datas) {
console.log(datas._id);
return datas._id;
});
}
console:
other player is acually undefined
57c1c0f3b6b20c011242bf22

You need to read about asynchronous calls. Which is db request. Simple fix is callback:
function something(data, callback) {
return callback('some data from db')
}
something('x', function(cb) {
console.log(cb)
}
it is good practise to return two values (error, callback). But you can read it later on.
There are also promises. You can read about them insted of callbacks, but it is recommended to know both.

Related

How to retrieve the content of a variable that is in a function? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I created this function:
var IDOfUserToKill = 'tralala';
export function getIDOfUserToKill(userID, gameID) {
let path = '/games/' + gameID + '/users/' + userID;
fb.database().ref(path).on('value', snapshot => {
IDOfUserToKill = '';
if (snapshot.val()) {
IDOfUserToKill = snapshot.val().userToKill;
console.log(IDOfUserToKill); // return the good ID
}
});
}
userID = IDOfUserToKill; // return "tralala" and not the good ID
Then I want to use the variable IDOfUserToKill outside this one. Because if I use IDOfUserToKill, it returns the value that was defined before the function (tralala) and not the ID.
How to retrieve the content of the variable? (I use React Native).
This function:
fb.database().ref(path).on('value', snapshot => {
IDOfUserToKill = '';
if (snapshot.val()) {
IDOfUserToKill = snapshot.val().userToKill;
console.log(IDOfUserToKill); // return the good ID
}
});
is asynchronous which means it moves on to another task before it finishes.
That is why inside on() you get the id that is in the database, while outside, here userID = IDOfUserToKill; you get the value 'tralala'.
To learn more about asychronous check this:
https://medium.com/google-developers/why-are-firebase-apis-asynchronous-callbacks-promises-tasks-e037a6654a93

How to pass back the array [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I am trying to pass the array named 'sheetsArray' out of the code below so that I may utilize it for some tasks. I cannot for the life of me figure out how to do this, despite trying many things and googling for hours. I'm sure it's easy but I'm not even sure what I should be searching that I'm not.
var sheetsArrayOut = sheets.spreadsheets.get({
auth: googleauth,
spreadsheetId: outputDOCID,
}, function(err,response) {
if (err) {
console.log('ERROR:' + err);
return
}
var sheets = response.sheets;
if (sheets.length == 0) {
console.log('No data found.');
} else {
var sheetsArray = [];
for (i = 0; i < sheets.length; i++) {
sheetsArray.push(sheets[i].properties.title);
}
}
console.log(sheetsArray[4]); // this returns the sheet name
return sheetsArray;
});
console.log(sheetsArrayOut[4]); // this returns undefined
It returns undefined because I suspect the function is asynchronous. In this instance you can probably use a callback to good effect:
function getData(function (sheetsArray) {
// do things with sheetsArray
});
function getData(callback) {
sheets.spreadsheets.get({
auth: googleauth,
spreadsheetId: outputDOCID,
}, function(err,response) {
// do a bunch of things
callback(sheetsArray);
});
}
The first = in var = sheetsArrayOut = sheets.spreadsheets.get(...) is invalid syntax.
Use var sheetsArrayOut = sheets.spreadsheets.get(...) instead.
Why don't you just reassign the value at the end of the request
var sheetsArrayOut;
sheets.spreadsheets.get({
auth: googleauth,
spreadsheetId: outputDOCID,
}, function(err,response) {
//your functional code
sheetsArrayOut = sheetsArray;
});

Undefined response in first api call in ionic3 [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I am trying to implement nested api calls in ionic3
submitLoginForm() {
var username = this.formData.value.username;
var password = this.formData.value.password;
var bodyjson;
var userId;
this.ApidataService.logincheck(username,password).subscribe(data => {
this.logindetail = data;
bodyjson = JSON.parse(this.logindetail._body);
userId = bodyjson.user.id;
if( userId != undefined){
this.ApidataService.userdata(userId).subscribe(data => {
this.userInfo = data;
});
}
console.log(userId);
});
console.log(this.userInfo);
}
Now when I call this function the nested api returns undefined for the first call and then from the second call onwards it returns proper values however when I try to log the argument that is being sent to the api I notice that the correct value is passed each time. I believe that this is due to some synchronization issues but am unable to figure out the issue and the solution for the same.
You can use flatMap here.It seems you don't need to retrieve results of both requests hence this should work for you.
import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/flatMap';
Then:
this.ApidataService.logincheck(username,password).flatMap(
(data) => {
this.logindetail = data;
bodyjson = JSON.parse(this.logindetail._body);
userId = bodyjson.user.id;
if( userId != undefined){
return this.ApidataService.userdata(userId);
}else{
return Observable.empty();
}
}).map((res: Response) => res ? res.json() : {})
.subscribe(data => {
this.userInfo = data ? data : {};
});
You can read more about flatMap here

undefined value return from node.js javascript class [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have declared class which generates the records and simply return it but it is returning undefined.
var classObj = new User();
var user = classObj.generateUserResponse(val1,mode);
console.log(user) //undefined
User.prototype.generateUserResponse = function (userid, mode) {
conn.query('select * from users where user_id = ?', [userid], function (err, user) {
if(mode == 'true') {
var genObj = new CustomerJSON();
userObj = genObj.generateUserCustomer(user);
console.log(userObj) // displays the value
return userObj;
} else {
// do something else
}
})
What I am doing above is creating a new class and passing a user object in a new class for further processing. I can console log and can see the data but when I return userObj it displays undefine.
It is right, because the invoked asynchronous function calls the callback (which returns the object to noone) after you log the object to console.
The function generateUserResponse returns no value.
Solution: make the required actions in the callback function.
Pavel is correct. Your function is asynchronous. You need a callback. Try something like this:
var classObj = new User();
classObj.generateUserResponse(val1, mode, function(userObj) {
console.log(userObj);
});
User.prototype.generateUserResponse = function(userid, mode, callback) {
//you could decide to return conn.query here and handle it differently above
conn.query('select * from users where user_id = ?', [userid], function(err, user) {
if (mode == 'true') {
var genObj = new CustomerJSON();
userObj = genObj.generateUserCustomer(user);
console.log(userObj) // displays the value
return callback(userObj);
} else {
// do something else
//THEN
return callback(userObj);
}
})
});
Or you could return conn.query(... and handle the promise it returns based on whatever library you're using.

variable is not overwritten nodejs [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
router.post('/loginv', function (req,res) {
var id = req.body.id;
var pass = req.body.pass;
if(login.login(id,pass)=='validated'){
res.sendfile('views/welcome.html');
}else{
res.send('dont give up');
}
var result = login.login(id,pass);
console.log(result);
});
module.exports={
login : function(id,pass){
var q = "SELECT * FROM user where id = ? and pass = ?";
var ret = 'default';
DB.DB.query(q, [id,pass], function (error,result) {
if(error){
console.log('not found');
ret = 'unrecognized';
} else{
console.log('found');
ret = 'validated';
}
});
return ret;
}};
console.log :
GET /login 304 4.028 ms - -
default
POST /loginv 200 40.558 ms - 12
found
found
as you can see the value ret returned from the following code is not being changed although it follows the procedure of the function properly..
i'm new to node js and js stuff so any comments and advice will definitely be helpful thx :)
DB.query() is async, so login function do not wait the execution of the code before returning ret. You need to add a callback to the login method (or use a promise).
A working code:
module.exports = {
login : function(id,pass,cb){
var q = "SELECT * FROM user where id = ? and pass = ?";
DB.DB.query(q, [id,pass], function (error,result) {
if(error){
console.log('not found');
cb(error, 'unrecognized');
} else{
console.log('found');
cb(null, 'validated');
}
});
}
};
The other file:
router.post('/loginv', function (req,res) {
var id = req.body.id;
var pass = req.body.pass;
login.login(id,pass, function(err, result) {
if (err) {
console.log(err);
res.send('dont give up');
return;
}
if (result === 'validated') {
res.sendfile('views/welcome.html');
}else{
console.log('Unknown error');
}
})
});
I suggest you to read links posted here and this question which can gives you an idea about callbacks and promises.
PS: I do not know which library you are using for DB, but you MUST sanitize input before doing queries, if the library does not do it for you

Categories