NodeJS Fetch Return always returns undefined - node.js

I'm trying to return a variable via a API, but when I go to return it, it always returns it as undefined
There is the function:
function getCityName()
{
console.log("Trying to return city location...");
var url = util.format('https://api.truckyapp.com/v2/map/%s/resolve?x=%s&y=%s', game.game.name, data.position.X, data.position.Y);
fetch(url).then(function(data) {
return data.json();
}).then(function(parsed){
return parsed.response.poi.realName;
});
}
Code to run the function:
var city = getCityName();
console.log("City name is: "+city)
INFO: The JSON shows correctly

You would need to return the final value returned by the callback from the getCityName function:
function getCityName()
{
console.log("Trying to return city location...");
var url = util.format('https://api.truckyapp.com/v2/map/%s/resolve?x=%s&y=%s', game.game.name, data.position.X, data.position.Y);
return fetch(url).then(function(data) {
return data.json();
}).then(function(parsed){
return parsed.response.poi.realName;
});
}
The above would cause getCityName to return a Promise. To get the actual value of the city, you would now have to wait for the Promise to resolve (using either await or then). Going by the standard followed, it would be:
getCityName().then(city => {
console.log("City name is: "+city);
});
Just to add, since getCityName would returning a Promise which might reject, it would be sensible to add a catch block while calling the function as well.

Related

Return value read Firebase database

I am making a function in nodejs to read a value from the database in Firebase and return it. I read in the that way and get the right value by the console.log(), but when i made the return of the value doesn´t work properly when i call that function
function test() {
database.ref(sessionId + '/name/').once("value").then((snapshot) => {
var name = snapshot.child("respuesta").val()
console.log(name);
return name;
});
}
If someone could help me. Thanks
You're not returning anything from test, so undefined is being implicitly returned. You can return the promise like this:
function test() {
return database.ref(// everything else is identical
}
Note that this will be returning a promise that resolves to the name, not the name itself. It's impossible to return the name, because that doesn't exist yet. To interact with the eventual value of the promise, you can call .then on the promise:
test().then(name => {
// Put your code that uses the name here
})
Or you can put your code in an async function and await the promise:
async function someFunction() {
const name = await test();
// Put your code that uses the name here
}

NodeJS Sequelize returning data from query

Totally new to Javascript and Node. I am trying to get started with Sequelize as an ORM and did a simple query
var employeeList = Employee.findAll().then(function(result){
console.log(result.length);
console.log(result[0].employeeName);
//how do I return this to a variable with which I can do further processing
return result;
});
//do something with employeeList
employeeList[0].employeeName //cannot read property of undefined
While the console logs print out the right name the employeeList itself does not contain any data. I tried printing the employeeList and it shows the promise
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined }
I did skim through the promise concept but could not get an east example as to how to return the results from the promise to a variable outside the function. I thought returning the result would do t he trick. Am I missing something here? I can understand that I could work on the results within the promise function. If the scenario is to make two database calls and then process the results of both calls to return a merged result how could that be done without getting results to variables.
so based on your post on comments of using to independent queries I'd like to show you how to use them properly:
//Each request in it's own function to respect the single responsability principle
function getAllEmployees() {
return Employee
.findAll()
.then(function(employees){
//do some parsing/editing
//this then is not required if you don't want to change anything
return employees;
});
}
function doAnotherJob() {
return YourModel
.findAll()
.then(function(response) => {
//do some parsing/editing
//this then is not required if you don't want to change anything
return response;
});
}
function do2IndependentCalls() {
return Promise.all([
getAllEmployees(),
doAnotherJob()
]).then(([employees, secondRequest]) => {
//do the functionality you need
})
}
Another way of doing is use async await :
async function getEmployees(){
var employeeList = await Employee.findAll().then(function(result){
console.log(result.length);
console.log(result[0].employeeName);
return result;
});
employeeList[0].employeeName;
}
The then method returns a Promise, not your employee list.
If you want to use the employee list, you should either do that in the function passed to your existing then call, or in a subsequent then call, as shown below.
Employee
.findAll()
.then(function(el){
console.log(el.length);
console.log(el[0].employeeName);
return el;
})
.then(function(employeeList){
//do something with employeeList
employeeList[0].employeeName
});

How to return a value from a function that uses 'http.get()' method in Node.js?

I have a simple HTTP GET function that only needs to return the response in a function, but right now this function is returning void.
The code in sitechecks.js
var checkSite = () => {
https.get('https://itmagazin.info', (res, err) => {
if (res.statusCode === 200 && res.statusMessage === 'OK') {
return `The site returned: ${res.statusMessage}`
} else return `Error, the site returned: ${err.message}`
})
}
module.exports = checkSite
And when I import the module in index.js, the console returns [Function: checkSite] and not the value itself.
// Index.js
var extSiteCheck = require('./sitechecks')
// This console prints [Function: checkSite] instead of "OK"
console.log(extSiteCheck.checkSite)
However, if I add the return statement on http.get() in the function, the console prints undefined. So I thought that this undefined is a progress, but I don't understand why does it return undefined?
(return http.get() in the checkSite function)
Any help, tips is appreciated.
Because callbacks in JavaScript are asynchronous, you can't return from within a callback.
That means this
console.log(extSiteCheck.checkSite)
runs before the request comes back.
You can try console logging within your callback (instead of trying to return a value), in order to see this in practice. But basically, whatever you are trying to achieve with the results of your get request, you need to do inside the callback.
mebbe something like ... console.log( extSiteCheck.checkSite() );

How to use result of a function that uses promises

I have a function,
asdf() {
var a = fooController.getOrCreateFooByBar(param);
console.log("tryna do thing");
console.log(a); //undefined
if (!a.property) {
//blah
}
that dies. getOrCreateFooByBar does a
Model.find({phoneNumber : number}).exec()
.then(function(users) {})
and finds or creates the model, returning it at the end:
.then(function(foo) { return foo}
How can I use the result of this in asdf()? I feel like this is a fairly easy question but I am getting stuck. If I try to do a.exec() or a.then() I get 'a cannot read property of undefined' error.
The main idea about Promises (as opposed to passed callbacks) is that they are actual objects you can pass around and return.
fooController.getOrCreateFooByBar would need to return the Promise it gets from Model.find() (after all of the processing done on it). Then, you'll be able to access it in a in your asdf function.
In turn, asdf() should also return a Promise, which would make asdf() thenable as well. As long as you keep returning Promises from asynchronous functions, you can keep chaining them.
// mock, you should use the real one
const Model = { find() { return Promise.resolve('foo'); } };
function badExample() {
Model.find().then(value => doStuff(value));
}
function goodExample() {
return Model.find().then(value => doStuff(value));
}
function asdf() {
var a = badExample();
var b = goodExample();
// a.then(whatever); // error, a is undefined because badExample doesn't return anything
return b.then(whatever); // works, and asdf can be chained because it returns a promise!
}
asdf().then(valueAfterWhatever => doStuff(valueAfterWhatever));

Javascript function using promises and not returning the correct value

As a relative beginning in Javascript development, I'm trying to understand this problem I'm encountering in a function I've built that will be a part of the code to connect to a postgreSQL database.
In this function, I'm using the knex query builder method to check if a table exists in a remote database, and this method resolves to a boolean that indicates whether the string you specified matches with a table of the same name in the database. I've a provided a sample example of the knex syntax so people better understand the function.
knex.schema.hasTable('users').then(function(exists) {
if (!exists) {
return knex.schema.createTable('users', function(t) {
t.increments('id').primary();
t.string('first_name', 100);
t.string('last_name', 100);
t.text('bio');
});
}
});
I am trying to make my function return a boolean by using the .every Array method, which checks each array and should every index pass the condition defined, the .every method should return a true value, otherwise false. I've built a function which takes an array of schema keys, or names of tables, and passes it to the .every method. The .every method then uses the knex.schema.hasTable method to return a true or false.
My concern is that through many different configurations of the function, I have not been able to get it to return a correct value. Not only does it return an incorrect value, which may have something to do with .every, which I believe can return "truthey" values, but after defining the function, I will often get a "Function undefined" error when calling it later in the file. Here is a sample of my function - again I think it is moreso my poor understanding of how returns, promises and closures are working together, but if anyone has insight, it would be much appreciated.
var schemaTables = ['posts','users', 'misc'];
// should return Boolean
function checkTable() {
schemaTables.every(function(key) {
return dbInstance.schema.hasTable(key)
.then(function(exists) {
return exists;
});
});
}
console.log(checkTable(), 'checkTable function outside');
// console.log is returning undefined here, although in other situations,
I've seen it return true or false incorrectly.
Your function is not working properly for two reasons:
You are not returning the in the checkTable function declaration, so it will always return undefined.
You should write:
function checkTable() {
return schemaTables.every(function(key) {
return dbInstance.schema.hasTable(key)
.then(function(exists) {
return exists;
});
});
}
Anyway you will not get what you want just adding return. I'll explain why in the second point.
Array.prototype.every is expecting a truthy or falsey value syncronously but what the dbInstance.schema.hasTable returns is a Promise object (and an object, even if empty, is always truthy).
What you have to do now is checking if the tables exist asynchronously, i'll show you how:
var Promise = require("bluebird");
var schemaTables = ['posts', 'users', 'misc'];
function checkTable(tables, callback) {
// I'm mapping every table into a Promise
asyncTables = tables.map(function(table) {
return dbInstance.schema.hasTable(table)
.then(function(exists) {
if (!exists)
return Promise.reject("The table does not exists");
return Promise.resolve("The table exists");
});
});
// If all the tables exist, Promise.all return a promise that is fulfilled
// when all the items in the array are fulfilled.
// If any promise in the array rejects, the returned promise
// is rejected with the rejection reason.
Promise.all(asyncTables)
.then(function(result) {
// i pass a TRUE value to the callback if all the tables exist,
// if not i'm passing FALSE
callback(result.isFulfilled());
});
}
checkTable(schemaTables, function (result) {
// here result will be true or false, you can do whatever you want
// inside the callback with result, but it will be called ASYNCHRONOUSLY
console.log(result);
});
Notice that as i said before, you can't have a function that returns a true or false value synchronously, so the only thing you can do is passing a callback to checkTable that will execute as soon as the result is ready (when all the promises fulfill or when one of them rejects).
Or you can return Promise.all(asyncTables) and call then on checkTable it self, but i'll leave you this as exercise.
For more info about promises check:
The bluebird website
This wonderful article from Nolan Lawson
Thanks Cluk3 for the very comprehensive answer. I actually solved it myself by using the .every method in the async library. But yes, it was primarily due to both my misunderstanding regarding returns and asynchronous vs synchronous.
var checkTablesExist = function () {
// make sure that all tables exist
function checkTable(key, done) {
dbInstance.schema.hasTable(key)
.then(function(exists) {
return done(exists);
});
}
async.every(schemaTables, checkTable,
function(result) {
return result;
});
};
console.log(checkTablesExist());
// will now print true or false correctly

Resources