What is the proper way to use Promise.reject with javascript - javascript

I have this following piece of code
new Promise((resolve, reject) => {
resolve(apiRequest(data))
reject(console.log('Error'))
}).then(response)
Both methods (resolve and reject) are being fired but I want to call reject only when something goes wrong.
How can I throw an error if something goes wrong on that case?
I checked that but it seems like I can not use an If statement to do that check.
new Promise((resolve, reject) => {
const printResult = apiRequest(data)
console.log(printResult) //Outputs Promise {<pending>}
resolve(printResult) //Then it works
reject(console.log('Error'))
}).then(response)
What would be the correct approach to reject a promise?

The easiest way would be with an if condition. i.e
new Promise((resolve, reject) => {
// do something...
if(somethingGoodHappened) {
resolve(data)
} else {
reject(error)
}
})
But usually when dealing with async requests, the thing you are calling will often be returning a promise, so you can attach the then and catch callbacks there.
apiRequest(data)
.then((result) => {
// all good
})
.catch((err) => {
console.log(err)
})

const mock_api = () => new Promise((res, rej) => {
const number = Math.floor((Math.random() * 100) + 1);
setTimeout(() => {
if (number%2==0) return res('randomly RESOLVED')
return rej('randomly REJECTED')
}, 2000)
})
const async_promise = () => new Promise(async (resolve, reject) => {
try {
const resolvedPromise = await mock_api()
resolve(resolvedPromise)
} catch (e) {
reject(e)
}
})
const classicPromise = () => new Promise((resolve, reject) => {
mock_api()
.then(resolve)
.catch(reject)
})
const makeAsyncRequest = async () => {
try {
const data = await async_promise()
console.log('ASYNC AWAIT RESOLVE', data)
} catch (e) {
console.log('ASYNC AWAIT ERR', e)
}
}
makeAsyncRequest()
classicPromise()
.then(r => console.log('PROMISE CHAIN RESOLVE', r))
.catch(e => console.log('PROMISE CHAIN ERR', e))

Because of you resolve before reject so it cannot run into reject,
You can use:
if (printResult) {
resolve(printResult)
} else {
reject(console.log('Error'))
}

You can catch exceptions and return them as rejected Promises
function asyncFunc() {
try {
doSomethingSync();
return doSomethingAsync()
.then(result => {
ยทยทยท
});
} catch (err) {
return Promise.reject(err);
}
}
Always check for err if there is any err return a promise (example below)
// Return new promise
return new Promise(function(resolve, reject) {
// Do async job
request.get(options, function(err, resp, body) {
if (err) {
reject(err);
} else {
resolve(JSON.parse(body));
}
})
})

Related

Issues with async/await

I'm trying to use async/await for a very basic promise, but I'm getting the error: SyntaxError: await is only valid in async function. However, I believe I'm using await for an async function.
function getNumber(mult) {
return new Promise((resolve, reject) => {
resolve(10);
}).then((val) => {
return new Promise((resolve, reject) => {
resolve(val * mult)
//reject("Error");
}).then((val2) => val2);
}).catch((err) => {
return err;
})
}
const calculate = async (x) => await Promise.resolve(getNumber(x))
const val = await calculate(2)
You cannot have the initial function with an await at the top level... just a modification.
function getNumber(mult) {
return new Promise((resolve, reject) => {
resolve(10);
}).then((val) => {
return new Promise((resolve, reject) => {
resolve(val * mult)
//reject("Error");
}).then((val2) => val2);
}).catch((err) => {
return err;
})
}
const calculate = (x) => Promise.resolve(getNumber(x));
const val = calculate(2).then(resp => {
console.log('do something with response: ', resp)
})
To only focus on why you're getting that error, the await in await calculate(2) isn't in an asynchronous function. If you can make it asynchronous function then do that but if not then you can use the .then() function like below:
calculate(2).then(val => {
//Your code here
}

How do i write promises in javascript

im trying to write a promise but seems to be missing something. here is my code:
const myPromise = new Promise(() => {
setTimeout(() => {
console.log("getting here");
return setinputs({ ...inputs, images: imageAsUrl });
}, 100);
});
myPromise
.then(() => {
console.log("getting here too");
firebase.database().ref(`collection/${idNode}`).set(inputs);
})
.then(() => {
console.log("all is set");
})
.catch((err) => {
console.log(err);
});
if i run the program, the first part of the promise is executing but all .then() functions arent executing. how do i fix this?
In this scheme, the promise callback has one (resolve) or two (resolve,reject) arguments.
let p = new Promise((resolve, reject)=> {
//do something
//resolve the promise:
if (result === "ok") {
resolve(3);
}
else {
reject("Something is wrong");
}
});
p.then(res => {
console.log(res); // "3"
}).catch(err => {
console.error(err); //"Something is wrrong
});
Of course, nowadays you can use async + await in a lot of cases.
You need to resolve the promise, using resolve() and also return the promise from firebase so the next .then in the chain works properly.
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("getting here");
// You have to call resolve for all `.then` methods to be triggered
resolve({ ...inputs, images: imageAsUrl });
}, 100);
});
myPromise
.then((inputs) => {
console.log("getting here too");
// You have to return a promise in a .then function for the next .then to work properly
return firebase.database().ref(`collection/${idNode}`).set(inputs);
})
.then(() => {
console.log("all is set");
})
.catch((err) => {
console.log(err);
});

JavaScript, Promise rejection

I'm trying to create this promise:
const getTocStatus = new Promise((resolve, reject) => {
const userInfo = Auth.currentUserInfo();
resolve(userInfo.attributes['custom:tocStatus']);
reject(new Error('Couldn\'t connect to Cognito'));
});
Then use it like this:
getTocStatus.then((response) => {
if (response === 'pending) { //do sth }
}, error => console.log('Error:', error)
But I'm getting the Error:
[TypeError: undefined is not an object (evaluating 'userInfo.attributes['custom:tocStatus']')]
What is badly coded on the promise and it call?
Lionel's answer is correct (I didn't know what Auth.currentUserInfo was, but there's no need for the Promise constructor since you're already dealing with promises:
const getTocStatus = async () => {
try {
const userInfo = await Auth.currentUserInfo()
return userInfo.attributes['custom:tocStatus']
} catch (e) {
new Error("Couldn't connect to Cognito")
}
}
// or with .then syntax
const getTocStatus = () =>
Auth.currentUserInfo()
.then((userInfo) => userInfo.attributes['custom:tocStatus'])
.catch((e) => { Promise.reject(new Error("Couldn't connect to Cognito")) })
The problem is that Auth.currentUserInfo gives you a promise, not a value, so you need to wait for it to complete before you can return its contents. Mario Vernari is also correct in that your error handling has problems too, but that's not why your code is crashing. This should hopefully fix both problems.
const getTocStatus = new Promise(async (resolve, reject) => {
try {
const userInfo = await Auth.currentUserInfo();
resolve(userInfo.attributes['custom:tocStatus']);
} catch (e) {
reject(new Error('Couldn\'t connect to Cognito'));
}
});
You must discriminate when there's an error and when it's not:
const getTocStatus = new Promise((resolve, reject) => {
try {
const userInfo = Auth.currentUserInfo();
resolve(userInfo.attributes['custom:tocStatus']);
}
catch (err) {
reject(new Error('Couldn\'t connect to Cognito'));
}
});
...or something like that.
Finally I did this, but I will fix my code using this:
const getTocStatus = new Promise((resolve, reject) => {
try {
Auth.currentUserInfo()
.then(response => {
resolve(response.attributes['custom:tocStatus'] || TocStatus.CONFIRMED);
})
.catch(err => console.log(err));
} catch (err) {
reject(new Error('Couldn\'t connect to Cognito'));
}
});
And:
getTocStatus.then((response) => {
console.log('response dentro del error', response);
if (response === 'pending') {
// do sth
}
}, error => console.log(error)

Rejecting a Promise with another new Promise

Im playing around with promises and i wanted a way of rejecting the promise inside of a then callback. So this is done by either calling throw return or return Promise.reject();. So far so good. You can accomplish this by also calling new Promise.reject(); withou a return.
Can someone explain why does this work?
new Promise((res, rej) => {
setTimeout(() => {
res(200);
}, 2000);
})
.then(() => {
console.log("ok1");
new Promise.reject();
// return Promise.reject();
.then(() => {
console.log("ok2");
})
.catch(() => {
console.log("error");
});
new Promise.reject()
Your code throws an exception. Exceptions cause promises to be rejected.
Because Promise.reject is not a constructor, this code works fine:
new Promise((res, rej) => {
setTimeout(() => {
res(200);
}, 2000);
})
.then(() => {
console.log('ok1')
Promise.reject('error!')
})
.then(() => {
console.log("ok2");
})
.catch(() => {
console.log("error");
});
New Promise.reject throws an error so the code jumps to the catch section with the following error : Promise.reject is not a constructor
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 2000);
}).then((res) => {
console.log(res);
new Promise.reject();
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log('error' ,err.message);
});

Promise do not bubble outside

I need to test function testMe using Mocha. But there is trouble when my unit test throw an error. Here is simpified example
function testMe(callback) {
new Promise((resolve, reject) => {
setTimeout(() => resolve([1,2,3]), 1000);
}).then((result) => {
callback(null, result);
}).catch((error) => {
callback(error, null)
});
}
testMe((err, result) => {
if(err) throw new Error();
if(result.length < 5) throw new Error();
});
In this example after throw runs catch block. But I need to run catch block only after reject.
EDIT:
In this case the script never stop. I don't understand why.
function testMe(callback) {
new Promise((resolve, reject) => {
setTimeout(() => resolve([1,2,3]), 1000);
}).then((result) => {
callback(null, result);
}, (error) => {
callback(error, null)
}).catch(() => {
console.log('Do not throw an error but still running');
});
}
testMe((err, result) => {
if(err) throw new Error();
if(result.length < 5) throw new Error();
});
When you work with promises then return the promises from functions instead of taking callbacks.
For example, instead of:
function testMe(callback) {
new Promise((resolve, reject) => {
// ...
});
}
use:
function testMe(callback) {
return new Promise((resolve, reject) => {
// ...
});
}
that way you will have the promise available to the caller of the function.
If you need to mix both styles, i.e. returning promises and taking callbacks, consider using a reliable library to handle that for you especially if you have trouble coding the translation between those style yourself:
http://bluebirdjs.com/docs/api/ascallback.html
http://bluebirdjs.com/docs/api/promise.promisify.html
You can simply return the promise from the test:
function testMe() {
// ^^ drop the callback
return new Promise((resolve, reject) => {
// ^^^^^^ return the promise
setTimeout(() => resolve([1,2,3]), 1000);
});
}
var p = testMe().then(result) => {
// ^^^^^ use the promise
if(result.length < 5) throw new Error();
});
return p; // to mocha

Categories

Resources