Rejecting from Promise.all - reactjs

I have an aysnc function that fetches data and returns the value of Promise.all i.e.
const fetchDownloadMenuData = async selectedItems => {
return Promise.all(
selectedItems.map(async item => {
try {
if (item.id === 'interviewGuide') {
const interviewGuide = await positionCandidatesService.getCandidate(
positionId,
candidateSelected.id
);
return interviewGuide.interviewGuide;
}
if (item.id !== 'overview' && item.id !== 'profile') {
const outcome = await outcomesService.get(candidateSelected.id, item.id);
return outcome;
}
return null;
} catch (err) {
appInsights.trackException({
error: new Error(`Error fetching candidate outcome: ${JSON.stringify(err)}`)
});
return null;
}
})
)};
I call this function like this:
try {
downloadData = await fetchDownloadMenuData(selectedItems);
} catch (err) {
appInsights.trackException({
error: new Error(`Could not fetch all PDF data: ${JSON.stringify(err)}`)
});
return;
}
But it never goes into the catch. Why is this? How do i get it to reject if all the promises don't resolve?
Thanks

You're not rejecting in the map...catch block, instead you're returning the null. That's why Promise.all not able to catch the exception. You need use throw in the catch block, Remember, throw will terminate the execution flow.
Try like this
selectedItems.map(async item => {
try {
...async stuff
} catch (err) {
appInsights.trackException({
error: new Error(`Error fetching candidate outcome: ${JSON.stringify(err)}`)
});
throw err OR throw new Error(err) <-- this is missing earlier.
}
})

Related

how do I print value in Text field from asyncstorage in react native?

I'm new in this!
_storeData = async () => {
try {
await AsyncStorage.setItem("#MySuperStore:key", "I like to save it.");
} catch (error) {
// Error saving data
}
};
_retrieveData = async () => {
try {
const value = await AsyncStorage.getItem("#MySuperStore:key");
if (value !== null) {
// We have data!!
return this.value;
}
} catch (error) {
console.log("error");
}
};
How do I print stored values into the Text element?
Originally there was
console.log(value); instead of return value;
Do I need to call function _storeData to store data? Like _storeData() or what I have to do.
No need to use this keyword on the return statement
_retrieveData = async () => {
try {
const value = await AsyncStorage.getItem("#MySuperStore:key");
if (value !== null) {
// We have data!!
console.log(value);
return value;
}
} catch (error) {
console.log("error");
}
};
_retrieveData async function return callback method

Handling promises while having setinterval

Sorry if title was a bit unclear, what I want to do is catch the member.send, but I don't know how to use try and catch when also using timeinterval. It gives me an error saying that I haven't handled it.
message.guild.members.forEach(member => {
try {
setInterval(() => {
member.send("hello");
}, 2000)
}
catch(e) {
console.log("couldnt send dm to a user!");
}
Second problem: Cannot read property of 'guild' of undefined, and UnhandledPromiseRejection
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// create an async function and run it
(async function(message) {
for (const [id, member] of message.guild.members) {
try {
// await will throw any error found and allow try/catch to work
await member.send("hello");
} catch (err) {
console.log("Found error", err);
}
await sleep(2000);
}
})();
try/catch doesn't work for promise rejections, nor does it work when wrapped around a setInterval. Just catch the promise:
member.send("hello").catch(err => {
console.error(`Got error ${err}.`);
});
If you want to send a message to each person then the best way is to use a promise-based sleep function:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// create an async function and run it
(async function() {
for (const [id, member] of message.guild.members) {
try {
// await will throw any error found and allow try/catch to work
await member.send("hello");
} catch (err) {
console.log("Found error", err);
}
await sleep(2000);
}
})();

Axios promise will never resolve

For the life of me, I can never get my Axios.post promise to resolve.
I know that my front end and backend are perfectly connected.
Try/catch blocks to return the resolved promise haven't worked either.
No matter what I do, I can never get inside of my promise.then() function. What am I doing incorrectly in my backend file?
CODE THAT HASN'T WORKED TO RESOLVE THE PROMISE
async handleDateSubmit() {
let resolvedPromise = await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
resolvedPromise
.then(response => {
//I can never get to here.
console.log("Made it inside");
})
.catch(err => console.log(err));
}
//---attempt two----//
async getResolvedPromise() {
try {
return await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
} catch (error) {
console.log(error);
}
}
async handleDateSubmit() {
let resolvedPromise = this.getResolvedPromise();
//work with resolvedPromsie
}
CURRENT CODE
//------------send_info.js front end file----------//
handleDateSubmit() {
Axios.post('http://localhost:3001/get_number_of_dates_from_email', {
email: this.state.user_email_m
})
.then((response) => {
//I can never get to here.
console.log("Made it inside");
})
.catch(err => console.log(err));
}
//---------------server.js backend file---------------//
router.route('/get_number_of_dates_from_email').post(function (req, res) {
//"user_email" is correct in my schema model and "req.body.email" is always what it should be
User.findOne({ user_email: req.body.email }, (err, foundUser) => {
console.log("Inside of findOne()");
if (err) {
return res.send(err);
}
else {
let numDates = foundUser.dates_list.length;
//I always get here and numDates is always correct
console.log("Number of dates: ", numDates);
return res.json({ "numDates": numDates }); //Should I be using res.send()?
}
});
});
It seems like you're confusing promises and resolved promises at times in your code
// Attempt one
async handleDateSubmit() {
try {
let resolvedPromise = await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
// Here resolvedPromise as stated by its name is not a promise anymore, thus you can't use .then()
// You can directly work with resolvedPromise as it contains the response.
} catch (e) {
console.error(e)
}
}
// Attempt two
async getResolvedPromise() {
try {
// Here you're returning the resolved promise, but the async await syntax turn your function into an AsyncFunction object
// This type of function will wrap the return value in a promise if it's not one
return await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
} catch (error) {
console.log(error);
}
}
async handleDateSubmit() {
// Thus you need to await the result of your function
let resolvedPromise = await this.getResolvedPromise();
}

How to wait for nested forEach statements with mongodb queries inside to return function

I am having a hard time figuring out the asynchronous behaviour of nested forEach() functions with node.js. I am not sure where I should create and return a promise and so on.
I have tried wrapping all the logic of the getFeed() function into a return new Promise(), but I think resolve is called before the nested forEach()'s are done.
friends = user_info.friends;
function GetFeed() {
let post_ids = [];
try {
friends.forEach(async function(friend_id) {
const posts = await db.collection('users').findOne(
{ _id: ObjectId(friend_id) },
{ projection: { posts: 1 }}
);
posts.posts.forEach(function(post_id) {
console.log(post_id);
post_ids.push(post_id);
});
});
return new Promise((resolve, reject) => {
resolve(post_ids);
});
} catch (err) {
return res.status(500).json({ error: 'Internal server error, unable to collection post ids from the database.' });
}
}
GetFeed()
.then((post_ids) => {
console.log(post_ids);
return res.status(200).json({ post_ids: post_ids });
})
the console.log() statements reveal that the GetFeed().then() executes before the console.log() statement in the inner forEach loop. I expect that the GetFeed().then() console.log would wait for the nest forEach logic to finish and then console.log the result.
From the docs:
forEach() executes the callback function once for each array element; unlike map() or reduce() it always returns the value undefined.
Meaning you cant wait for it as you can never get a promise to return from it.
You should use a for or while loop or a library like bluebird to iterate over an array and return promises.
You can use a promise array an await them.
friends = user_info.friends;
async function GetFeed() {
let post_ids = [];
let postsPromiseArray = await Promise.all(
friends.map(friend_id => {
return db.collection('users').findOne(
{ _id: ObjectId(friend_id) },
{ projection: { posts: 1 } }
);
})
)
postsPromiseArray.forEach(posts => {
posts.posts.forEach(function (post_id) {
post_ids.push(post_id);
});
})
return post_ids;
}
GetFeed()
.then((post_ids) => {
console.log(post_ids);
return res.status(200).json({ post_ids: post_ids });
})
I think this could help you to get a desired output.
friends = user_info.friends;
async function GetFeed() {
let post_ids = [];
try {
await friends.forEach(async function(friend_id) {
const posts = await db.collection('users').findOne(
{ _id: ObjectId(friend_id) },
{ projection: { posts: 1 }}
);
posts.posts.forEach(function(post_id) {
console.log(post_id);
post_ids.push(post_id);
});
});
return post_ids;
} catch (err) {
return res.status(500).json({ error: 'Internal server error, unable to collection post ids from the database.' });
}
}
var post_ids = GetFeed()
console.log(post_ids);
return res.status(200).json({ post_ids });

Persisting data if none exists for a certain key using AsyncStorage

I'm trying to set up a function where I first check to see if I have a value for a certain key, and if I do not, I use the axios library to get a value from the web and persist it as that key's value instead. Here is my code:
async getName() {
try {
const value = await AsyncStorage.getItem('dummy'); //the value should be a JSON object
if (value !== null){
return value.name;
}
else {
axios.get('https://api.github.com/users/dummy')
.then(function (response) {
console.log(response);
try {
await AsyncStorage.setItem('dummy', 'dummyval');
} catch (error) {
console.log(error);
}
return(response.name);
})
.catch(function (error) {
console.log('Error fetching name: ' + error.response);
});
}
} catch (error) {
console.log(error);
}
I'm pretty new to React Native, so I'm sure this looks like a mess. I know I must be doing something wrong because I keep getting a syntax error on the second use of await. Does anyone know how to properly structure these calls?
You need to declare axios's success handler using async keyword. In your code, you have written like .then(function (response), this should be changed to .then(async function (response).
Consider following changes.
async getName() {
try {
const value = await AsyncStorage.getItem('dummy'); //the value should be a JSON object
if (value !== null){
return value.name;
}
else {
axios.get('https://api.github.com/users/dummy')
.then(async function (response) {
console.log(response);
try {
await AsyncStorage.setItem('dummy', 'dummyval');
} catch (error) {
console.log(error);
}
return(response.name);
})
.catch(function (error) {
console.log('Error fetching name: ' + error.response);
});
}
} catch (error) {
console.log(error);
}
}
Hope this helps!

Resources