Issue with promise: ReferenceError: reject is not defined - javascript

I am working with some own built promise examples to understand how this function is working.
That following code produces the error
ReferenceError: reject is not defined
I start this with node Promise.js and use node version 8.11.3
Here is my code, the part which produces the error is commented with "problem
function testPromise () {
//part 1
function checkCountOnServer () {
return new Promise(function (resolve, reject) {
var available = false
if (available) {
resolve('available')
}
else {
reject('not available')
}
})
}
function checkPayment () {
return new Promise(function (resolve, reject) {
var booleanTest = true
if (booleanTest) {
resolve('payment done')
}
else {
reject('no payment received')
}
})
}
var checkCountOnServerVar = checkCountOnServer()
checkCountOnServerVar.then(function (resolve) {
console.log(resolve)
return resolve(checkPayment())
}, function (reason) {
console.log(reason) //works
reject(reason) // problem
}).then(function (value) { console.log(value) },
function (rejected) {
console.log(rejected) //problem
})
}
testPromise()
I actually expect the message 'not available' two times.
Even if I change reject(reason) to reject('test') I get the same error.
Help me please.

checkCountOnServerVar.then(function (resolve) {
The then callback is called with whatever value the promise was resolved to, which is "payment done" in your case,and that is not a function, so you can't call it. To chain a promise from inside a then handler, just return it:
checkCountOnServerVar.then(function (status) {
console.log(status);
return checkPayment();
})
Additionally your error catcher does not make sense at all,
function (reason) {
console.log(reason) //works
reject(reason) // problem
}
As reject is not defined, and as you actually don't handle the error. If you don't handle the error, there is no sense in attaching a handler, otherwise you should return a value the chain can continue with, such as:
function(error) {
console.error("Something bad happened", error);
return "An error occured, but we don't mind...";
}
To sum up:
checkCountOnServer()
.then(serverCount => checkPayment())
.then(payment => console.log(payment))
.catch(error => console.error(error));

Related

named promise chainy for normal promises that handle events

I am trying to create a named promise chain. I am not sure of how to achieve this. The goal is following:
function multiplepromises() {
var prom = function (resolve, reject) {
var lifecycleeventone = new someEvent();
var lifecycleeventtwo = new someEvent();
var lifecycleeventthree = new someEvent();
var lifecycleeventfour = new someEvent();
var lifecycleeventfive = new someEvent();
lifecycleeventone.on(function () {
try {
resolve("eventone")
} catch {
reject("eventone")
}
})
lifecycleeventtwo.on(function () {
try {
resolve("eventtwo")
} catch {
reject("eventtwo")
}
})
lifecycleeventthree.on(function () {
try {
resolve("eventthree")
} catch {
reject("eventthree")
}
})
lifecycleeventfour.on(function () {
try {
resolve("eventfour")
} catch {
reject("eventfour")
}
})
lifecycleeventfive.on(function () {
try {
resolve("eventfive")
} catch {
reject("eventfive")
}
})
maineventlikefinallySOcalledalways.on(function(){
try {
resolve("maineventlikefinallySOcalledalways")
} catch {
reject("maineventlikefinallySOcalledalways")
}
})
}
return prom
}
multiplepromises()
.onlifecycleeventoneAsProm((result)=> result) //eventone promise resolve
.onlifecycleeventoneerrorAsProm((error)=> error) //eventone
.onlifecycleeventtwoAsProm((result)=> result) //eventtwo promise resolve
.onlifecycleeventtwoerrorAsProm((error)=> error) //eventtwo
.onlifecycleeventthreeAsProm((result)=> result) //eventthree promise resolve
.onlifecycleeventthreeerrorAsProm((error)=> error) //eventthree
.onlifecycleeventfourAsProm((result)=> result) //eventfour promise resolve
.onlifecycleeventfourerrorAsProm((error)=> error) //eventfour
.onlifecycleeventfiveAsProm((result)=> result) // eventfive promise resolve
.onlifecycleeventfiveerrorAsProm((error)=> error) //eventfive
.then((result)=> result) // maineventlikefinallySOcalledalways promise resolve
.error((error)=> error) // maineventlikefinallySOcalledalways promise reject
multiplepromises()
.onlifecycleeventoneAsProm((result)=> result) //eventone promise resolve
.onlifecycleeventoneerrorAsProm((error)=> error) //eventone
.onlifecycleeventtwoAsProm((result)=> result) //eventtwo promise resolve
.onlifecycleeventtwoerrorAsProm((error)=> error) //eventtwo
.onlifecycleeventthreeAsProm((result)=> console.log("test"))
// lifecycleeventthree promise reject stops here and
// doesnt continue to .then/.error since there was no return from this lifecycle event(promise)
I have read this and this doesnt solve the purpose completely.
Handling multiple catches in promise chain and https://javascript.info/promise-chaining
Dont want to use Rx and want to keep to vanilla js
You can‘t achieve something like that with Promises.
Instead you can make a function that returns an object with event registrar functions, which return again the object.
Here is a simple example:
function test() {
return new (function() {
this.eh = {};
this.on = (event, handler) => {
this.eh[event] = handler;
return this;
}
this.call = (event, ...args) => {
if (typeof this.eh[event] === 'function') {
this.eh[event](...args);
}
}
Promise.resolve().then(() => {
// Do your stuff...
// Example:
this.call('msg', 'This is a message.');
setTimeout(() => {
this.call('some-event', 'This is some event data.');
this.call('error', 'This is an error.');
}, 1000);
});
})()
}
test()
.on('msg', (msg) => console.log(`Message: ${msg}`))
.on('some-event', (data) => console.log(`Some event: ${data}`))
.on('error', (err) => console.log(`Error: ${err}`))
I hope that‘s what you were up to.
Edit:
Here's another attempt: https://jsfiddle.net/bg7oyxau/

Node.js: Unhandled promise rejection - UnhandledPromiseRejectionWarning

I have a Node.js app. This app has a button that starts a process. The steps in that process return promises. I'm trying to chain these promises together. For some reason, I'm receiving an UnhandledPromiseRejectionWarning. However, in my mind, I've set this up correctly. My code looks like this:
var myButton = document.getElementById('myButton');
if (myButton) {
console.log('here');
myButton.addEventListener('click', executeAction('0'));
}
function executeAction(input) {
let param1 = 'A';
let promise = new Promise(function(resolve, reject) {
try {
executeStep1()
.then(result => executeStep2(param1, result, input))
.then(result => function(result) {
console.log('All done');
resolve(result);
})
.catch(err => reject(err))
;
} catch (ex) {
reject(ex);
}
});
return promise;
}
function executeStep1() {
let promise = new Promise(function(resolve, reject) {
try {
setTimeout(function() {
resolve('[something]');
}, 3000);
} catch (ex) {
reject();
}
});
return promise;
}
function executeStep2(p1, p2, p3) {
let promise = new Promise(function(resolve, reject) {
try {
setTimeout(function() {
console.log('step 2 has executed');
resolve('awesome!')
}, 3000);
} catch (ex) {
reject(ex);
}
});
return promise;
}
I've confirmed that the executeStep2 function runs to completion. I'm basing this in the fact that I can see "step 2 has executed" in the console window. However, to my surprise, I never see "All done" printed in the console window. Instead, I see the UnhandledPromiseRejectionWarning mentioned above. I don't understand two things about this result:
Why am I not seeing "All done" in the console? Shouldn't that function get executed after executeStep2 has resolved?
Where is the rejection coming from? I don't see anything that's rejecting this.
Thank you very much for your help!
executeStep1()
.then(result => executeStep2(param1, result, input))
.then(result => { // no function(result) here
console.log('All done');
resolve(result);
})
.catch(err => reject(err))
;
The error is generated from when you call the function(s) that uses promises:
myButton.addEventListener('click', executeAction('0'));
You need to catch rejections there also.
myButton.addEventListener('click', executeAction('0')
.catch((error) => console.log('ERROR', error));
The rejections are caught inside the functions, but not in the outer scope because executeAction('0') returns a promise, or it would but you are using it as a non-async function, so its creating a promise and then returning a pending promise without waiting for it to be resolved. That looks like what's causing the rejection, and its also not handled for the above reason.
This will fix it:
function executeAction(input) {
let param1 = 'A';
return new Promise(function(resolve, reject) {
try {
executeStep1()
.then(result => executeStep2(param1, result, input))
.then(result => function(result) {
console.log('All done');
resolve(result);
})
.catch(err => reject(err))
;
} catch (ex) {
reject(ex);
}
});
}
You should look into async/await. It can clean this code up significantly.
async function getSomething() {
try {
// throw 'Test error detected.'
return 'test'
}
catch (e) {
throw e
}
}
async function testing() {
try {
const sample = await getSomething()
return sample
} catch (e) {
throw e
}
}
testing()
.then((data) => console.log(data))
.catch((err) => console.log(err))
Run this above example, and then uncomment the throw. Use this pattern for maximum winning. Exceptions should be thrown to the surface level where the functions are called, displayed, used, rendered, etc. Functions should simply throw the error out.
This allows you to use error handling middleware, higher-order functions, listeners, logging, etc.

JavaScript/Node.JS returning a promise in another promise not working

I'm a bit confused with those promise things and can't understand why I can't return a promise into another promise. My problem is the following, I have a function save :
save(Driver) {
this.exists(Driver).then(exist => {
if(exist) {
return new Promise(function (resolve, reject) {
if (exist === true) {
resolve(true);
} else if (exist === false) {
resolve(false);
} else {
reject(err);
}
});
}
});
};
As easy as it is, when I try to call that function as following :
save(driver).then(this.common.saveSuccess(res))
.catch(this.common.noSuccess(res));
I'm getting an error saying that Cannot read property 'then' of undefined and I can't understand why as I'm returning a promise.
Thank for the help
Your save function is very complicated. You don't need nested promise here, just return the result (promise) from this.exists function:
save(Driver) {
return this.exists(Driver);
};
Also, you use this function incorrectly. save function can be resolved with true or false values, so you need to validate this value in then callback and use catch callback for possible errors:
save(driver)
.then(exists => {
if (exists) {
this.common.saveSuccess(res);
} else {
this.common.noSuccess(res)
}
})
.catch(err => // process error here);

How to .catch a Promise.reject

I have a helper function for using fetch with CouchDB which ends as:
...
return fetch(...)
.then(resp => resp.ok ? resp.json() : Promise.reject(resp))
.then(json => json.error ? Promise.reject(json) : json)
and when I use it elsewhere, I was under the impression that I could .catch those explicit rejections:
above_function(its_options)
.then(do_something)
.catch(err => do_something_with_the_json_error_rejection_or_resp_not_ok_rejection_or_the_above(err))
but alas, I can't seem to be able to get a hold of the rejections.
The specific error I'm after is a HTTP 401 response.
What gives?
(Please note that there are implicit ES6 return's in the .thens)
function test() {
return new Promise((resolve, reject) => {
return reject('rejected')
})
}
test().then(function() {
//here when you resolve
})
.catch(function(rej) {
//here when you reject the promise
console.log(rej);
});
Make sure every call to a then() returns a value.
For e.g.
var url = 'https://www.google.co.in';
var options = {};
var resolves = Promise.resolve();
resolves.then(() => {
console.log('Resolved first promise');
var fetchPromise = fetch(url, options);
fetchPromise.then(() => {
console.log('Completed fetch');
});
})
.catch(error => {
console.log('Error', error);
});
Notice the console shows an uncaught exception. However, if you returned the inner promise (or any other value, which ends up turning into a promise via resolve), you end up flattening the promise so exception bubble up.
var url = 'https://www.google.co.in';
var options = {};
var resolves = Promise.resolve();
resolves.then(() => {
console.log('Resolved first promise');
var fetchPromise = fetch(url, options);
return fetchPromise.then(() => {
console.log('Completed fetch');
});
})
.catch(error => {
console.log('Error', error);
});
Notice the exception bubbles up to the outer promise. Hope this clears up things a little bit.
Why not wrap it in a try / catch block
// define a failing promise
const test = ()=> new Promise((resolve, reject) => reject('rejected'));
// using an immediately executing function to call an async block
(async ()=> {
try {
await test(); // => this will throw an error
} catch (er) {
console.log(er); // 'rejected'
}
})();
Promise rejections fall to the second param of the then function.
function test() {
return new Promise((resolve, reject) => {
return reject('rejected')
})
}
test().then(function() {
//here when you resolve
}, function(rej) {
//here when you reject the promise
console.log(rej)
})

If else in Promise

I try to refacter code from using callback to Promise but I got some weird behavior from Promise(bluebird)
here is the main logic
function func1(callback) {
func2()
.then(function(resultFromFunc2) {
if (resultFromFunc2 === true) {
callback(null, resultFromFunc2)
} else {
return func3()
}
})
.then(function(resultFromFunc3) {
console.log('Func 3', resultFromFunc3)
callback(null, resultFromFunc3)
})
.catch(function(err) {
console.log('error', err)
})
}
func1(function(err, result) {
console.log('func1', err, result);
})
and in func2 and func3 is just a simple resolve
function func2() {
return new Promise((resolve, reject) => {
resolve(true)
});
}
function func3() {
return new Promise((resolve, reject) => {
resolve(true)
});
}
If func2 resolve true code should stop running in the first then, but I found the second then is called
here is result from terminal.
func1 null true
Func 3 undefined
func1 null undefined
How could I stop calling the second then when func2 is resolve true
#Phattahana,
Just posting my thoughts on your question.
As you have said in your answer, you shouldn't be calling callback() from the 1st then. Or else you should be ready to change the workflow and remove the 2nd then. there are lot many possibilities.
In a specific scenario, where you want the code to be executed just like the question you posted (ie; if the if condition is true, donot call 2nd then - scenario), you can have your code like below.
var Promise = require("bluebird");
function func1(callback) {
func2()
.then((resultFromFunc2) => {
return new Promise((resolve, reject) => {
if (resultFromFunc2 === true) {
callback(null, resultFromFunc2);
} else {
resolve(func3());
}
});
}).then((resultFromFunc3) => {
console.log('Func 3', resultFromFunc3)
callback(null, resultFromFunc3)
}).catch((err) => {
console.log('error', err)
});
}
func1((err, result) => {
console.log('func1', err, result);
return 1;
});
function func2() {
return new Promise((resolve, reject) => {
resolve(false)
});
}
function func3() {
return new Promise((resolve, reject) => {
resolve(true)
});
}
The code inside the 1st then should be made into a separate promise resolving function and should be resolving it only if the condition is not met.
Hope its clear.
Thanks,
The problem here is with your second then section. If you remove it, everything should work as expected (if I understand correctly). See the snippet below - if you change func2 to resolve(false), func3 will be called, otherwise the callback will be called.
function func1(callback) {
func2()
.then(function(resultFromFunc2) {
if (resultFromFunc2 === true) {
callback(null, resultFromFunc2)
} else {
return func3()
}
})
.catch(function(err) {
console.log('error', err)
})
}
func1(function(err, result) {
console.log('func1', err, result);
})
function func2() {
return new Promise((resolve, reject) => {
console.log('func2');
resolve(true)
});
}
function func3() {
return new Promise((resolve, reject) => {
console.log('func3')
resolve(true)
});
}
I just found the solution,
function func1(callback) {
func2()
.then(function(resultFromFunc2) {
if (resultFromFunc2 === true) {
return 'result from func2'
} else {
return func3()
}
})
.then(function(result) {
callback(null, result)
})
.catch(function(err) {
console.log('error', err)
})
}
I should not callback in the first then because whatever return from first then it send to the second then.
I miss understand behavior of Promise. first I think it will not call the second then if the first then doesn't return Promise.

Categories