why i keep getting undefined when i console.log this function - javascript

Hello I'm a complete beginner in node js and I just learned about promises and I'm trying to using them in my code
but when I try to console.log this function I keep getting undefined and I don't know why
I will be very thankful if you help me
function weather(location) {
const request = require('request');
const errorMessage = 'Something went wrong. Please check you internet connection or the URL you provided.';
new Promise((resolve, reject) => {
const geoUrl = `https://api.mapbox.com/geocoding/v5/mapbox.places/
${location}.json?access_token=pk.eyJ1Ijoic3F1YXJlc2NyaXB0IiwiYSI6ImNrc3lwZmdtejFpdzQycHB1eTVpODNwdmYifQ.izw6cVMKDZme4KJwxHdxjw`;
request({
url: geoUrl,
json: true
}, (error, request) => {
if (error) {
reject(errorMessage)
} else {
resolve(`http://api.weatherstack.com/current?access_key=
c704f108fc10fbbdb15c384daff85a20&query=${request.body.features[0].center.reverse()}`)
}
})
}).then(url => {
request({
url: url,
json: true
}, (error, request) => {
if (error) {
return errorMessage
} else {
const currData = request.body.current;
return `${currData.weather_descriptions[0]}, It's currently ${currData.temperature} degrees out. There is a ${currData.humidity}% chance of rain.`;
}
});
}).catch(message => message)
};
console.log(weather('NYC'))

You need to return the promise..
return new Promise((resolve,reject)=>{
And then the console will log "Unresolved promise." Or something like that. If you want to wait for the promise to resolve, you need to use await or the then method:
weather('NYC').then(console.log)
You also need to make sure your promise is being resolved or rejected:
if (error){reject(errorMessage)}
else {
const currData=request.body.current;
resolve(`${currData.weather_descriptions[0]}, It's currently ${currData.temperature} degrees out. There is a ${currData.humidity}% chance of rain.`);
}
All these little errors would be easier to spot if your code was formatted properly.
Also, don't put your private access tokens in public forums.
You can find lots of tutorials on how promises work around the internet. Here's the MDN manual page.

Related

Having trouble returning a promise and then consuming it after a database call

Im learning Javascript and im up to a section on Promises.
So decided to try and convert some of my earlier projects to use Promises.
But I cant get my head around it. Iv read a lot of guides and browsed through this site but I still cant understand why this isnt working.
This the function im working with, trying to do a database call that returns a promise, that can then be logged or whatever.
const getID = function (product) {
let query = `select typeID from invTypes where UPPER(typeName) =UPPER('${product}')`;
return new Promise((resolve, reject) => {
resolve(
DB.get(query, function (err, result) {
if (err) {
Bot.say(`Error looking up ${product}`);
} else {
console.log(result.typeID); //587
return result.typeID;
}
})
);
});
};
getID(product).then((data) => console.log(data)); //Database {}
The console outputs
Database {}
587
so the .then(data => console.log(data)) //Database {} Is still happening before the promise is returned,
as you can see the other log from earlier up inside the function is actually logging after it.
Can someone help me with this iv been at this one function for hours now haha. I think I have some kind of fundamental misunderstanding that Im not picking up on from my bootcamp videos or anything im reading.
In promise code, you use resolve() in the asynchronous function's callback function to return values.
const getID = function(product) {
let query = `select typeID from invTypes where UPPER(typeName) =UPPER('${product}')`;
return new Promise((resolve, reject) => {
DB.get(query, function(err, result) {
if (err) {
Bot.say(`Error looking up ${product}`);
reject(`Error looking up ${product}`);
} else {
console.log(result.typeID); //587
resolve(result.typeID);
}
})
});
};

Get request data from a promise (RIOT API)

I have a request made with "request" from NodeJs, and I want to get the data with a promise. All good because the console shows me the information that I am requested. The problem is when I call the promise function, and the console shows me this. How can I get the real value?
let leagueTier = (accId) => new Promise(async (resolve, reject) => {
request({
url: `https://${reg}.api.riotgames.com/lol/league/v4/entries/by-summoner/${accId}${key}`,
json: true
}, (error, response, body) => {
if (!error && response.statusCode === 200) {
resolve(body[0].tier.toLowerCase())
} else {
reject(Error('It broke'))
}
})
}).then(function(res) {
return res;
})
This is where I call the function
.attachFiles([`./images/${leagueTier(body.id)}.png`])
(node:5868) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, stat 'D:\Dev\shen-bot\images[object Promise].png'
How can I access the string of the request I made? Maybe I shouldn't use promises?
The leagueTier return value will be a promise that eventually resolves or rejects into a value. You can't simply add the return value as part of a string. You can either use await or then to wait for the value to come through.
// asuming you are in async function context
.attachFiles([`./images/${await leagueTier(body.id)}.png`]);
// or
leagueTier(body.id).then(tier => {
.attachFiles([`./images/${tier}.png`]);
});
Note that your current code:
.then(function(res) {
return res;
})
Does absolutely nothing and can be omitted.

What am i doing wrong with Promise rejections here?

So I've made a bit of reusable code here for node, and I'm applying it via async / await. Albeit I'm sure I am misunderstanding a lot here when working with this... But, I swear, I have one project I'm using this code that it works, and another where it doesn't.
Im using request and request-promise.
UrlRequest: function( opts ) {
return new Promise( (resolve, reject) => {
request( opts,
function(error, request, body) {
if (error)
reject( {error: true, msg: error} );
else
resolve( {body, request} );
});
})
.catch(err => reject( {error: true, msg: err} ));
}
I am fairly sure the .catch() is wrong. But it didn't error out in my 1st project. So i'm trying to figure out the proper way of doing this. The few articles I've looked through is where I came up with this function for usage. I also know if any error actually happens ( this case included ), it will throw a UnhandledPromiseRejectionWarning error. So how is this properly handled?
How I use it:
(async () => {
var result = await Promise.UrlRequest( {
url: "...",
method: "GET",
headers: DefaultHeaders
} );
// do stuff with result...
}) ();
Since you already installed request-promise, you don't need constructing the Promise as you are doing. Simply use the it instead of request then you would have a promise returned. Something similar to this should work:
const request = require('request-promise')
request(opts)
.then((res) => {
// Process res...
})
.catch((err) => {
// Handle error...
});
You can proceed to wrap it in your UrlRequest function and use with async as follows:
UrlRequest: async ( opts ) => {
try {
const response = await request(opts);
return response;
} catch (error) {
// Handle error
}
}
In the case that you want to use then() and catch(), you can do this:
UrlRequest: ( opts ) => {
return request(opts)
.then(response => response)
.catch (error) {
// Handle error
}
}
With request-promise, you don't need to write your own Promise wrapper
// make sure you're using the promise version
const request = require('request-promise')
var opts = {
...
resolveWithFullResponse: true // <--- <--- to get full response, response.body contains the body
};
// if you dont plan to use UrlRequest as constructor, better name is starting with lowercase: urlRequest, some naming convention
UrlRequest: async function( opts ) {
let res;
try {
res = await request(opts);
} catch (e) {
// handle error
throw e
}
return res;
}
Note: async function wraps the return in Promise

meteor.call with callback returning undefined

I appreciate that there are many questions on this but I can't seem to find a relevant answer.
I am using a Meteor call with a callback to a method on the server that shrinks an URL via bitly, but although this runs on the server, I am getting a undefined response back on the client.
Any ideas here is the code?
Client
Meteor.call('bitlyShrink','http://test.com', function(error, response) {
console.log(error);
console.log(response);
})
Server
Meteor.methods({
bitlyShrink(longurl) {
check (longurl, String);
const BitlyClient = require('bitly'),
bitly = BitlyClient('token');
bitly.shorten( longurl )
.then( function ( response ) {
console.log(response);
return response;
})
.catch( (error ) => {
return error;
});
}
});
That's a common mistake made while using Promises in Meteor methods.
To make Meteor resolve a Promise and return result to a client you should return the Promise at the end of this method:
Meteor.methods({
bitlyShrink(longurl) {
check (longurl, String);
const BitlyClient = require('bitly'),
bitly = BitlyClient('token');
const bitlyPromise = bitly.shorten(longurl);
// do something else, if needed
return bitlyPromise;
}
});
You should not add .catch(), it will be added by Meteor automatically.
Useful article to read: Using Promises and async/await in Meteor.

Uncaught exception onReject callback Promise

Since yesterday , I try to understand a behavior that I did not know about onReject Promise callback. In fact, I work with an API (return json data) and Superagent for make request. I have this class:
class Api
{
constructor(uri) {
...
}
// Simple GET HTTP Request
get(...) {
var url = this.buildUrl(...);
this.requestPending = request.get(url);
return new Promise((resolve, reject) => {
this.requestPending.end((err, res) => {
if (err) {
reject(res.body.error);
} else {
resolve(res.body);
}
});
});
}
}
What I do not understand is that:
reject(res.body.error);
throw an exception (res.body.error contains a simple string). Indeed, firebug display this error:
uncaught exception: ...
Could you explain this behavior ?
PS: I work with babel for transpile js.
Edit
I tested with when librairie but I have the same result. However, when I write:
reject(new Error("foo"));
The onReject callback is never call:
when.all([
api.get(...),
api.get(...)
]).then(data => {
console.log(data)
}, err => {
console.log(err);
})
and in the browser:
I continue my research.
Edit 2
Really sorry , I deserve to be whipped on the public square !!!. In fact, I had to change one file instead of two. Really, really sorry !!
I dont know whether it is silly or not,may be the scope for requestPending might be the problem.sorry if it sounds silly,
var url = this.buildUrl(...),self = this;
this.requestPending = request.get(url);
return new Promise((resolve, reject) => {
self.requestPending.end((err, res) => {
if (err) {
reject(res.body.error);
} else {
resolve(res.body);
}
});
});
}
}

Categories

Resources