Value is always undefined returning from promise - javascript

I am currently working with the blackberry dynamics SDK.
I am currently using the http request functionality for the SDK but every time I want to return a response from a http call its always undefined - I tried promisifying it to return a value but to no avail.
It originally used two callbacks - which would rightly return me undefined, but if I make it a promise should it not return me a value.
Code
function constructGDHttpPostRequest(reqObj) {
let PostRequest = window.plugins.GDHttpRequest.createRequest("POST", URI + reqObj.endPoint, 30, false);
PostRequest.addRequestHeader('Content-Type', 'application/json');
PostRequest.addHttpBody(reqObj.body);
return SendRequest(PostRequest).then(function (httpRes) {
console.log(httpRes);
return httpRes;
})
}
function SendRequest(Request) {
return new Promise(function (resolve) {
resolve(Request.send(sendSuccess));
})
}
function sendSuccess(response) {
console.log("Received valid response from the send request");
let Response = window.plugins.GDHttpRequest.parseHttpResponse(response);
return JSON.parse(Response.responseText);
}
I have tried using some of the questions asked relating to something like this but it still returned undefined from the promise.
Cheers in advance.

As per #Nikos M. suggestion this is what ave done and now works as expected.
I needed to resolve the callback in order to return a value.
I would like to make the callback a little cleaner with some suggestions.
function constructGDHttpPostRequest(reqObj) {
let PostRequest = window.plugins.GDHttpRequest.createRequest("POST", URI + reqObj.endPoint, 30, false);
PostRequest.addRequestHeader('Content-Type', 'application/json');
PostRequest.addHttpBody(reqObj.body);
return SendRequest(PostRequest).then(function (httpRes) {
console.log(httpRes);
return httpRes;
})
}
function SendRequest(Request) {
return new Promise(function (resolve) {
Request.send(function (response) {
resolve(JSON.parse(window.plugins.GDHttpRequest.parseHttpResponse(response).responseText));
});
})
}

Related

Javascript Fetch API status returning undefined

With the deprecation of XMLHttpRequest, I have been trying to rewrite a javascript function that checks if a url exists by using Fetch. My console log results in the correct value, but my return statement is always undefined. What am I doing wrong?
function urlExists(url) {
var request = new Request(url);
fetch(request).then(function(response) {
console.log(response.status);
return response.status != 404;
});
}
EDIT: I jumped the gun on a bug based on this error message in console [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. My bug was actually elsewhere in my code. Sorry for the confusion!
The problem is that you trying to do a sync operation by writing an async code. Both return statements in your code are relevant to their respective scope. You need to have a callback to return the response from fetch.
function urlExists(url, callback) {
var request = new Request(url);
fetch(request).then(function(response) {
console.log(response.status);
callback(response.status != 404);
});
}
/* Usage */
urlExists('http://example.com', (isExist) => {
if(isExist) {
console.log('URL found');
}
console.log('URL not found');
})
The code you have provided does not handle error part. Hence, That might be the reason it was not working.
function urlExists(url) {
var request = new Request(url);
return fetch(request).then(function(response) {
return (response.status != 404);
}, function(error){
return false;
});
}
urlExists("https://jsonplaceholder.typicode.com/todos/1").then(result=>{ console.log(result); });
urlExists("https://google.com").then(result=>{ console.log(result); });
I have tested this and working fine.
Convert it into this
function urlExists(url) {
return new Promise((resolve,reject)=>{
var request = new Request(url);
fetch(request).then(function(response) {
resolve(response.status != 404);
});
});
}
To Use It
urlExists("https://www.google.com").then(result=>{
console.log(result);
});
Your function returns a promise, so make sure you're using await or .then(...) in outer code to access the response correctly

Node JS: Returning Data with Callback Function from API using http

I'm starting to learn Node.js and I am trying to build an app with the Express framework that will query the Coinbase API and get data on the price of Bitcoin.
I have been struggling with one thing though and because I am new to callback functions on node it does not help.
I am able to fully query the API and get the data but when it comes to somehow returning the price, it always comes back as "undefined".
I had this problem previously with simple queries that did not use callbacks so I assumed it was to do with the lack of the callback. However, I am still getting the same problem now and I have tried numerous iterations. I can't seem to find a solution. Any help would be appreciated.
var url = 'https://api.coinbase.com/v2/prices/spot?currency=USD';
function makeCall (url, callback) {
https.get(url,function (res) {
res.on('data', function (d) {
callback(JSON.parse(d));
});
res.on('error', function (e) {
console.error(e);
});
});
}
function handleResults(results){
return Number((results.data.amount))*14.5;
}
console.log(makeCall(url, function(results){
handleResults(results);
}));
makeCall() doesn't actually return anything. So when you call:
console.log(makeCall(url, function(results){
handleResults(results);
}));
you are writing the immediate return value of makeCall() (which is undefined) to the console. The return from your handleResults() happens too late for the console.log() to get.
It take a little getting used to. But you need to make sure when you need a value from an async callback, you wait to access it. For example this would work:
function handleResults(results){
console.log(Number((results.data.amount))*14.5;)
}
Learning to use promises can makes some of this more intuitive and easier to read.
Using promises you could write it like:
const https = require('https')
var url = 'https://api.coinbase.com/v2/prices/spot?currency=USD';
function makeCall (url) {
return new Promise((resolve, reject) => {
https.get(url,function (res) {
res.on('data', function (d) {
resolve(JSON.parse(d));
});
res.on('error', function (e) {
reject(e)
});
});
})
}
function handleResults(results){
return Number((results.data.amount))*14.5;
}
makeCall(url)
.then(function(results){
console.log(handleResults(results))
})
.catch(console.log)

Issue with Nodejs promise

I have a sequence of function calls, connected with ES6 promises. Apparently, there is something wrong with this implementation, as API calls to the endpoint are not returning anything and the browser is stuck waiting for a response.
Please advise.
module.exports.insertTreatmentDetails = function (req, res) {
var doctorId = 10000
var departmentId = 10000
var procedureid = 10000
var hospitalSchema = new hospitalModel();
var p = new Promise(function (resolve, reject) {
counterSchema.getNext('Treatment.doctor.doctorId', collection, function (doctorId) {
doctorId = doctorId;
})
counterSchema.getNext('Treatment.departmentId', collection, function (departmentId) {
departmentId = departmentId
})
counterSchema.getNext('Treatment.procedureid', collection, function (procedureid) {
procedureid = procedureid
})
}).then(function () {
setData()
}).then(function (){
hospitalSchema.save(function (error, data) {
if (error) {
logger.error("Error while inserting record : - " + error)
return res.json({ "Message": error.message.split(":")[2].trim() });
}
else {
return res.json({ "Message": "Data got inserted successfully" });
}
});
});
};
The short answer is that you aren't calling resolve or reject inside the first promise in your chain. The promise remains in a pending state. Mozilla has a good basic explanation of promises.
How to Fix
It appears that you want to retrieve doctorId, departmentId, and procedureId before calling setData. You could try to wrap all three calls in one promise, checking whether all three have returned something in each callback, but the ideal is to have one promise per asynchronous task.
If it's feasible to alter counterSchema.getNext, you could have that function return a promise instead of accepting a callback. If not, I would recommend wrapping each call in its own promise. To keep most true to what your code currently looks like, that could look like this:
const doctorPromise = new Promise((resolve, reject) =>
counterSchema.getNext('Treatment.doctor.doctorId', collection, id => {
doctorId = id;
resolve();
}));
Then you could replace the first promise with a call to Promise.all:
var p = Promise.all([doctorPromise, departmentPromise, procedurePromise])
.then(setData)
.then(/* ... */);
Promises allow you to pass a value through to the next step, so if you wanted to get rid of your broadly-scoped variables (or set them in the same step where you call setData), you could just pass resolve as your callback to counterSchema.getNext and collect the values in the next step (also how you'd want to do it if you have counterSchema.getNext return a promise:
Promise.all([/* ... */])
.then(([doctorID, departmentID, procedureID]) => {
// If you aren't changing `setData`
doctorId = doctorID;
departmentId = departmentID;
procedureid = procedureID;
setData();
// If you are changing `setData`
setData(doctorID, departmentID, procedureID);
}).then(/* ... */).catch(/* I would recommend adding error handling */);

Promise syntax / alternative [duplicate]

This question already has answers here:
Why does the Promise constructor need an executor?
(2 answers)
Closed 6 years ago.
I wish to return a Promise which is self-resolved at a later time, but it seems that my syntax is invalid, and I'm curious what a better implementation would be. Why is an executor required for the Promise constructor?
promise = new Promise() is invalid because I need to supply a function
function getDetails (someHash) {
var url = "http://somewebsite.com/" + someHash,
promise = new Promise();
makeAjaxRequest(url, function (response) {
promise.resolve(response.data);
});
setTimeout(function () {
promise.reject("timeout");
}, 500);
return promise;
}
function makeAjaxRequest (url, callback) {
var someResponse = {data: "some data"};
setTimeout(function () {
callback(someResponse);
}, 200);
}
Is there a better way to implement this functionality?
Note: If you want to convert a callback API to promises see this question.
Let's start with something that should be said from the get go. An executor is not required in order to design promises. It is entirely possible to design a promises implementation that does something like:
let {promise, resolve, reject} = Promise.get();
If you promise not to tell anyone, I'll even let you in on a little secret - this API even exists from a previous iteration of the spec and in fact even still works in Chrome:
let {promise, resolve, reject} = Promise.defer();
However, it is being removed.
So, why do I need to pass an executor?
I just answered your other question about why an executor is an interesting design. It's throw-safe and it lets you take care of interesting things.
Can I still get the resolve, reject functions? I need those
In my experience, most of the times I needed resolve/reject I didn't actually need them. That said - I did in fact actually need them a couple of times.
The specifiers recognized this and for this reason the executor function is always run synchronously. You can get the .defer interface it just isn't the default:
function defer() {
let resolve, reject, promise = new Promise((res, rej) => {
[resolve, reject] = [res, rej];
});
return {resolve, reject, promise};
}
Again, this is typically not something you want to do but it is entirely possible that you have a justifiable use case which is why it's not the default but completely possible.
Your actual code
I would start with implementing things like timeout and a request as primitives and then compose functions and chain promises:
function delay(ms) {
return new Promise(r => setTimeout(r, ms));
}
function timeout(promise, ms) {
return Promise.race([
promise,
delay(ms).then(x => { throw new Error("timeout"); })
]);
}
function ajax(url) { // note browsers do this natively with `fetch` today
return new Promise((resolve, reject) => { // handle errors!
makeAjaxRequest(url, (result) => {
// if(result.isFailure) reject(...);
if(result.status >= 400) reject(new Error(result.status));
else resolve(result.data);
});
});
}
Now when we promisified the lowest level API surface we can write the above code quite declaratively:
function getDetails (someHash) {
var ajax = makeAjaxRequest("http://somewebsite.com/" + someHash);
return timeout(ajax, 500);
}
You need to pass a function to the Promise constructor (more info), which will get called to provide the resolve and reject functions:
function getDetails (someHash) {
var url = "http://somewebsite.com/" + someHash;
return new Promise(function(resolve, reject) {
makeAjaxRequest(url, function(err, response) {
if (err)
reject(err);
else
resolve(response.data);
});
setTimeout(function () {
reject("timeout");
}, 500);
});
}
function makeAjaxRequest (url, callback) {
var someResponse = {data: "some data"};
setTimeout(function () {
callback(null, someResponse);
}, 200);
}
I've also taken the liberty to make makeAjaxRequest use the standard convention of passing errors as first argument (because I assume that at some point you want to replace the setTimeout() with an actual AJAX request).

Nodejs Promise for custom api

I am new to nodejs and using promise and actually this is my first real app with nodejs.
So i have been reading all day and i am a bit confused.
So this is my module :
function User() {
var self = this;
self.users = {};
self.start = function (user, botId) {
return new Promise(function () {
return get(user).then(function (data) {
debug(data);
if (data.botId.indexOf(botId) === false) {
return Repo.UserBotModel.addUser(user.id, botId).then(function () {
data.botId.push(botId);
return data;
});
} else
return data;
});
});
};
self.getDisplayName = function (user) {
if (user.real_name)
return user.real_name;
if (user.last_name)
return user.firstname + ' ' + user.last_name;
return user.first_name;
};
/**
* check if user exist in our database/memory cache and return it,
* otherwise insert in the database and cache it in memory and the return it
* #param user
*/
function get(user) {
return new Promise(function () {
//check if user is loaded in our memory cache
if (self.users.hasOwnProperty(user.id))
return self.users[user.id];
else {
//get from database if exist
return Repo.UserModel.get(user.id).then(function (rows) {
if (rows && rows.length) {
//user exist cache it and resolve
var data = rows[0];
if (data.botId && data.botId.length)
data.botId = data.botId.split(',');
else
data.botId = [];
self.users[user.id] = data;
//------------------------------ code execution reaches here
return data;
}
else {
//user dose not exist lets insert it
return Repo.UserModel.insert(user).then(function (result) {
return get(user);
});
}
});
}
});
}
}
I call the start method witch calls the private get method the call reaches return data;(marked with comment) but then function dose not gets executed in the start method ???
So what am i doing wrong?
UPDATE : Sorry I forgot to mention that I am using bluebird and not the native promise if that makes a difference?
You cannot return from the Promise constructor - you have to call resolve (expected to happen asynchronously). You're not supposed to use the Promise constructor at all here. You can just omit it, and it should work.
The methods from your Repo.UserModel already return promises, so you do not have to create new ones using new Promise.
You can read the values inside those promises using then.
then also provides a way to transform promises. If you return a value in a function passed to then, then will return a new promise that wraps the value you returned. If this value is a promise, it will be awaited.
To convert a value to a promise, you can use Promise.resolve.
Knowing that, you can simplify get like so:
function get(user) {
if (...) {
return Promise.resolve(...)
} else {
return Repo.UserModel.get(...).then(function(rows) {
...
return ...
})
}
}
This version of getwill always return a promise that you can use like so:
get(...).then(function(resultOfGet) {
// process resultOfGet
})

Categories