How to use map inside try/catch? - javascript

I have a sample, kindly have a look, if I am doing it the right way,
export const create = async ({ invitationList, testId }) => {
try {
const promises = invitationList.map(async invitationTo => {
return new Promise(async (resolve, reject) => {
const invitation = await InterviewSchedule({
invitationTo,
testId
}).save();
resolve(invitation);
});
});
Promise.all(promises).then(value => {
console.log(value);
});
} catch (error) {
throw error;
}
};
I am unable to catch the error inside the catch block.

The classic try/catch control flow for errors only works when you await the promises. In your code, you are not awaiting the Promise.all. Try this instead:
export const create = async({
invitationList,
testId
}) => {
try {
const promises = invitationList.map(invitationTo =>
new InterviewSchedule({
invitationTo,
testId
}).save());
const results = await Promise.all(promises);
console.log(results);
} catch (error) {
throw error;
}
};

Related

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)

Capturing errors with Async/Await

I have a part of my code that makes several API calls to different endpoints and I want to know if any of those calls fail so I can display an appropriate error message. Right now, if an error happens in one() it will stop all other calls from happening, but that's not what I want; If an error occurs, I want it to populate the errors object and have the program continue on.
async function gatherData() {
let errors = { one: null, two: null, three: null };
const responseOne = await one(errors);
const responseTwo = await two(errors);
const responseThree = await three(errors);
if (!_.isNil(errors.one) || !_.isNil(errors.two) || !_.isNil(errors.three)) {
// an error exists, do something with it
} else {
// data is good, do things with responses
}
}
gatherData();
async function one(errors) {
await axios
.get("https://jsonplaceholder.typicode.com/comment")
.then(res => {
return res;
})
.catch(err => {
errors.one = err;
return err;
});
}
async function two(errors) {
await axios
.get("https://jsonplaceholder.typicode.com/comments")
.then(res => {
return res;
})
.catch(err => {
errors.two = err;
return err;
});
}
async function three(errors) {
await axios
.get("https://jsonplaceholder.typicode.com/comments")
.then(res => {
return res;
})
.catch(err => {
errors.three = err;
return err;
});
}
If you pass the errors to the async functions, so pass the errors object as parameter
const responseOne = await one(errors);
const responseTwo = await two(errors);
const responseThree = await three(errors);

React Native: Rendering text from a function

In my loop I have to get the address of lat and long. I have this function using reverseGeolocation
_getLocationAddress = async location => {
return new Promise((resolve, reject) => {
try {
const { status, data } = await srs.getReverseGeolocation(location);
if (data) {
resolve(data.results[0].formatted_address);
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
I also tried not wrapping into promise and not async it doesn't work it keeps returning a promise object. What I need from there is to return the data result into string. Here's my render
renderNewSR() {
const { delivery_items } = this.state;
return delivery_items.map((prop, key) => {
const location = {
latitude: parseFloat(prop.pickuplat),
longitude: parseFloat(prop.pickuplong)
};
//console.log(location);
const address = "";
this._getLocationAddress(location)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
.....
What is alternative solution to this. I want the result from google api return as string and can be displayed in render.
You are not declaring arrow function async inside new Promise but you are trying to use await inside that function.
Just add async (resolve, reject) to solve the issue.
Also you don't need to use async in async location as you are not awaiting any promise but returning promise in wrapper function.
_getLocationAddress = async location => {
return new Promise(async (resolve, reject) => {
try {
const { status, data } = await srs.getReverseGeolocation(location);
if (data) {
resolve(data.results[0].formatted_address);
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
Hope that helps!!!

Possible Unhandled Promise Rejection (id: 0) React Native AsyncStorage

I am promisifying the React Native AsyncStorage getItem method but I am being warned that it is returning a possible unhandled promise rejection. Here's what I'm doing, what's wrong with my code?
In App.js ComponentDidMount()
componentDidMount() {
ConnectyCube.init(...config);
authInitialization = async () => {
const locallyStoredPhoneNumber = await getStoredPhoneNumber();
console.log(locallyStoredPhoneNumber);
authorizeFirebase(this.getFirebaseAccessToken);
this.props.authorizing(true);
}
authInitialization();
}
Then in localStorage.js
export const getStoredPhoneNumber = () => {
return new Promise((resolve, reject) => {
AsyncStorage.getItem('#phone_number', (error, result) => {
result ? resolve(result) : reject(error);
})
})
}
Thanks in advance.
UPDATE
I have now added error handling:
export const getStoredPhoneNumber = () => {
return new Promise((resolve, reject) => {
AsyncStorage.getItem('#phone_number', (error, result) => {
result ? resolve(result) : reject(error);
})
}).catch(error => console.error(error))
}
Seems to work - here's my extra logic that depends on the result of the AsyncStorage call:
componentDidMount() {
ConnectyCube.init(...config);
authInitialization = async () => {
const locallyStoredPhoneNumber = await getStoredPhoneNumber();
locallyStoredPhoneNumber !== undefined
? authorizeFirebase(this.getFirebaseAccessToken) && this.props.authorizing(true)
: this.setState({ newUser: true })
}
authInitialization();
}
Seems like this should work:
async componentDidMount() {
ConnectyCube.init(...config);
try {
const locallyStoredPhoneNumber = await AsyncStorage.getItem('#phone_number');
locallyStoredPhoneNumber !== undefined
? authorizeFirebase(this.getFirebaseAccessToken) && this.props.authorizing(true)
: this.setState({ newUser: true })
} catch (e){
// handle error
}
}
One way to handle promise rejection would be to use try...catch block where your promise is being returned.
try{
const locallyStoredPhoneNumber = await getStoredPhoneNumber();
} catch(error){
//Error handling code here
}
You need to 'catch' any errors which might be thrown and handle them (otherwise React will complain):
componentDidMount() {
authInitialization = async () => {
try {
const locallyStoredPhoneNumber = await getStoredPhoneNumber();
...
} catch (e) {
console.log(e) //handle error }
}
authInitialization();
}
}

Passing an error from one async function to another

I have a convoluted system, which totally works on async/await. What I want is to handle multiple types of errors from an async function in one and only try/catch block. Which means that I call this function from another async function.
But the concept of handling exceptions in a parent async function seems to fail. In the below example what I get - is just a warning about unhandled promise rejection, and the catch block in the parent won't ever get an error. I've tried this also with simply throwing and error, but unsuccessfully either.
const die = (word) => new Promise((resolve, reject) => reject(word));
const live = () => new Promise((resolve, reject) => resolve(true));
const daughterAsync = async () => {
await live();
try {
await die('bye');
} catch (err) {
return Promise.reject(err);
}
try {
await die('have a beatiful time');
} catch (err) {
return Promise.reject(err);
}
await live();
};
const parentAsync = async () => {
try {
daughterAsync();
} catch(err) {
console.log('error catched'); // never happens
console.log(err);
}
};
parentAsync();
I have a feeling that I don't get something about async functions to perform such a stunt
Your daughterAsync(); line only starts the promise running, but it doesn't save the reference to it or wait for it to resolve. You need to await the promise returned by daughterAsync inside of parentAsync's try block in order to catch errors in daughterAsync:
const die = (word) => new Promise((resolve, reject) => reject(word));
const live = () => new Promise((resolve, reject) => resolve(true));
const daughterAsync = async () => {
await live();
try {
await die('bye');
} catch (err) {
return Promise.reject(err);
}
try {
await die('have a beatiful time');
} catch (err) {
return Promise.reject(err);
}
await live();
};
const parentAsync = async () => {
try {
await daughterAsync();
} catch(err) {
console.log('error catched');
console.log(err);
}
};
parentAsync();

Categories

Resources