This is probably a silly question, but mid promise chain, how do you reject a promise from inside one of the then functions? For example:
someActionThatReturnsAPromise()
.then(function(resource) {
return modifyResource(resource)
})
.then(function(modifiedResource) {
if (!isValid(modifiedResource)) {
var validationError = getValidationError(modifiedResource);
// fail promise with validationError
}
})
.catch(function() {
// oh noes
});
There's no longer a reference to the original resolve/reject function or the PromiseResolver. Am I just supposed to add return Promise.reject(validationError); ?
Am I just supposed to add return Promise.reject(validationError);?
Yes. However, it's that complicated only in jQuery, with a Promise/A+-compliant library you also could simply
throw validationError;
So your code would then look like
someActionThatReturnsAPromise()
.then(modifyResource)
.then(function(modifiedResource) {
if (!isValid(modifiedResource))
throw getValidationError(modifiedResource);
// else !
return modifiedResource;
})
.catch(function() {
// oh noes
});
Use Promise.reject
Like this
function test()
{
return new Promise((resolve, reject) => {
resolve(null)
}).then(() => console.info('yes')).then(() => {
return Promise.reject('hek');
})
}
test().then(() => console.info('resolved')).catch(() => console.info('rejected'))
Related
I´m new to JavaScript and a little bit confused about Promises, this is what I have:
export const testFunction = () => dispatch => {
otherFunction().then(( response ) => {
//do something...
return response;
}).catch(( error ) => {
//do something...
return error;
});
}
In another file I'm trying to get the value returned from the then like this:
let result = this.props.testFunction()
And like this:
let result = this.props.testFunction ().then(( result ) => {
console.log(result);
}).catch(( error ) => {
console.log(result); // undefined
});
But I get undefined as the result, what is the correct way of getting that value?
testFunction is not returning a Promise so you can't use then or catch and returns undefined because well, it's not returning any thing.
Try to return a promise like the example below however I am not sure what the dispatch argument supposed to do so I have removed it and hopefully this'll help:
export const testFunction = () => {
return new Promise((resolve, reject) => {
otherFunction().then(( response ) => {
//do something...
resolve(response);
}).catch(( error ) => {
//do something...
reject(error);
});
});
}
when you are trying to return a promise to use it in another file, you must use the following syntax:
const testFunction = () => {
return new Promise((resolve, reject) => {
if (error) {
return reject(error); // this is the value sent to .catch(error)
}
return resolve(valueToReturn); // this is the value sent to .then(result)
});
}
This is how you create a promise to use where you want, if it has an error it will sent to catch block, otherwise you should see the console.log(result) value.
And in your external file you can use the syntax that you are using, try it in that way to see the console.log value.
Here is a link to see more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
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);
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)
})
How should I stop the promise chain in this case?
Execute the code of second then only when the condition in the first then is true.
var p = new Promise((resolve, reject) => {
setTimeout(function() {
resolve(1)
}, 0);
});
p
.then((res) => {
if(true) {
return res + 2
} else {
// do something and break the chain here ???
}
})
.then((res) => {
// executed only when the condition is true
console.log(res)
})
You can throw an Error in the else block, then catch it at the end of the promise chain:
var p = new Promise((resolve, reject) => {
setTimeout(function() {
resolve(1)
}, 0);
});
p
.then((res) => {
if(false) {
return res + 2
} else {
// do something and break the chain here ???
throw new Error('error');
}
})
.then((res) => {
// executed only when the condition is true
console.log(res)
})
.catch(error => {
console.log(error.message);
})
Demo - https://jsbin.com/ludoxifobe/edit?js,console
You could read the documentation, which says
Promise.then return a rejected Promise if the input function throws an error, or the input function returns a rejected Promise.
If you prefer, you could read the Promise A spec, in the section about then, where promise2 refers to the resulting promise:
If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.)
If you prefer, you could read the excellent 2ality blog:
then() returns a new promise Q (created via the constructor of the receiver):
If either of the reactions returns a value, Q is resolved with it.
If either of the reactions throws an exception, Q is rejected with it.
You could read the brilliant YDKJS:
A thrown exception inside either the fulfillment or rejection handler of a then(..) call causes the next (chained) promise to be immediately rejected with that exception.
You could move the chain into the conditional branch:
p.then((res) => {
if(true) {
return Promise.resolve(res + 2).then((res) => {
// executed only when the condition is true
});
} else {
// do something
// chain ends here
}
});
Just use something like: reject('rejected')
in the else of the first task.
P
.then((res) => {
if(true) {
return res + 2
} else {
reject('rejected due to logic failure' }
})
.then((res) => {
// executed only when the condition is true
console.log(res)
})
Alternatively u can also add a catch section to ur first task with .catch()
Hope this helps.
How should I stop the promise chain in this case?
Execute the code of second then only when the condition in the first then is true.
var p = new Promise((resolve, reject) => {
setTimeout(function() {
resolve(1)
}, 0);
});
p
.then((res) => {
if(true) {
return res + 2
} else {
// do something and break the chain here ???
}
})
.then((res) => {
// executed only when the condition is true
console.log(res)
})
You can throw an Error in the else block, then catch it at the end of the promise chain:
var p = new Promise((resolve, reject) => {
setTimeout(function() {
resolve(1)
}, 0);
});
p
.then((res) => {
if(false) {
return res + 2
} else {
// do something and break the chain here ???
throw new Error('error');
}
})
.then((res) => {
// executed only when the condition is true
console.log(res)
})
.catch(error => {
console.log(error.message);
})
Demo - https://jsbin.com/ludoxifobe/edit?js,console
You could read the documentation, which says
Promise.then return a rejected Promise if the input function throws an error, or the input function returns a rejected Promise.
If you prefer, you could read the Promise A spec, in the section about then, where promise2 refers to the resulting promise:
If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.)
If you prefer, you could read the excellent 2ality blog:
then() returns a new promise Q (created via the constructor of the receiver):
If either of the reactions returns a value, Q is resolved with it.
If either of the reactions throws an exception, Q is rejected with it.
You could read the brilliant YDKJS:
A thrown exception inside either the fulfillment or rejection handler of a then(..) call causes the next (chained) promise to be immediately rejected with that exception.
You could move the chain into the conditional branch:
p.then((res) => {
if(true) {
return Promise.resolve(res + 2).then((res) => {
// executed only when the condition is true
});
} else {
// do something
// chain ends here
}
});
Just use something like: reject('rejected')
in the else of the first task.
P
.then((res) => {
if(true) {
return res + 2
} else {
reject('rejected due to logic failure' }
})
.then((res) => {
// executed only when the condition is true
console.log(res)
})
Alternatively u can also add a catch section to ur first task with .catch()
Hope this helps.