So, from code below im getting array of udefined but to be honest idk why and how to fix it...
const promises = sessionsIds.map((id) =>
stripe.checkout.sessions
.listLineItems(id, { limit: 100 })
.then((err, lineItems) => {
return lineItems;
})
);
const usernames = await Promise.all(promises);
I have also tried with async await but the result is still the same.
Assuming that stripe.checkout.sessions.listLineItems(id, { limit: 100 }) is returning a regular, standard promise, then the problem is that you're treating is like a regular asynchronous callback with (err, value) as the functions arguments. That's not how .then() works. The first argument to .then() is a function that will be called with one argument, the resolved value. In fact, you probably don't even need a .then() here.
You can change to this:
const promises = sessionsIds.map((id) =>
stripe.checkout.sessions.listLineItems(id, { limit: 100 })
);
const usernames = await Promise.all(promises);
Or, simplifying further:
const usernames = await Promise.all(sessionsIds.map((id) =>
stripe.checkout.sessions.listLineItems(id, { limit: 100 })
));
Note, the .then() handler here is not necessary (assuming stripe.checkout.sessions.listLineItems(id, { limit: 100 }) already returns a promise). If you want to use a .then() handler, it would go like this:
const promises = sessionsIds.map((id) =>
stripe.checkout.sessions.listLineItems(id, { limit: 100 })
.then((lineItems) => {
console.log(lineItems);
return lineItems;
});
);
const usernames = await Promise.all(promises);
Where you pass it a function as the first argument and it gets one argument (the resolved value).
Related
How can I return the value from an async function in React Native ?
I am trying to compress images which was given by user.
Here is my compress function where compress each image
const compressFunction = async (item, format = SaveFormat.JPEG) => {
const result = await manipulateAsync(
item.uri,
[],
{ compress: 0, format }
)
return result
};
Here is the function I try to call it. This is not working, console.log return Promise { _u 0, _v 0, _w null, _x null }. compressFunction is working and i can console.log and see the result for each return of "compressFunction(item)" but i can't see them in array list.
const compressImages = (items) => {
const list = items.map( async (item) => ( await compressFunction(item)) )
console.log(list)
}
But for example when i try to call like that it is working.
const compressImages = async (items) => {
const list= await compressFunction(items[0])
console.log(list)
}
I couldn't catch what im doing wrong, I'm working on it for hours. If someone can help me I would be grateful
try await Promise.all(items.map(compressFunction))
Calling list.map(async function) will transform each element in list into a Promise.
Edit: if you make this much more verbose you can see what's going on here
const promises = items.map(item => {
return new Promise((res) => {
compressFunction(item).then(result => {
return res(result);
});
});
});
// Now with the list of promises we have to use the Promise api
// to wait for them all to finish.
Promise.all(promises).then(results => {
// do stuff with results
});
Async/await is just shorthand for this syntax
I am trying to make an app that will allow me to update a textbox after receiving a change in a variable. However the variable takes a long time to update, and await does not work to wait for my variable to update probably because of the timeout function I used. How do I create a listener or something of that sort to check for any variable changes?
Below is my code snippet
const [banana, setBanana] = useState(-1);
const updateLocation = async() => {
const majorSig = scheduledScan();
setBanana(majorSig);
}
const scheduledScan = async() => {
beaconScan();
// Scans for 20 seconds
setTimeout( async()=> {
beaconStop();
await getAndUpdateUserLoc();
// console.log("Loggged: ", await getUserLoc());
// console.log("major: ", await getSignificantMajor());
currentMajor = await getSignificantMajor();
return currentMajor;
}, 20000);
}
When I run updateLocation(), my code is supposed to run for 20 second. I want it to wait until it finishes running scheduledScan() and returns a value to majorSig before it runs the setState function. However right now all it does is run scheduledScan() and update setState immediately to a wrong value. What should I do to make it behave in the way I want?
Thank you.
Firstly, in your async updateLocation function, your await statement is missing. Let's add it appropriately:
const updateLocation = async () => {
const majorSig = await scheduledScan();
setBanana(majorSig);
};
Then, It would be a good idea if you follow a promise approach in your time-limited function by using a Promise.race which lets your function either time out or successfully return a value:
const scheduledScan = async () => {
beaconScan();
return Promise.race([
async () => {
beaconStop();
await getAndUpdateUserLoc();
// console.log("Loggged: ", await getUserLoc());
// console.log("major: ", await getSignificantMajor());
currentMajor = await getSignificantMajor();
return currentMajor;
},
new Promise((_, reject) => setTimeout(() => reject(new Error('Request timed out')), 20000)),
]);
};
I want to write a function that will get the value for the collection, as shown in the picture:
And here is my code, I really don't know what to do after the "then()":
const getLocation = () => {
firebase
.firestore()
.collection("users")
.doc(currentUser.uid)
.get()
.then((querySnapshot) => {});
};
Note that currentUser is redux, meaning that the query will execute only for the current user that is logged in
If you want to return the value of businessLocation only you can do this:
const getLocation = () => {
return firebase.firestore()
.collection("users")
.doc(currentUser.uid)
.get()
.then(function(doc) {
if (doc.exists) {
data = doc.data();
return data.businessDetails.businessLocation;
} else {
return "";
}
});
};
You can get more information on how to get data in firestore at the Official Documentation.
Note: This makes your function become an asynchronous function. Therefore you should call it as follows:
getLocation().then(result => {
//Do whatever you want with the result value
console.log(result);
})
Curious issue I'm having dealing with some callback functions. I need to make a series of API calls that all return promises then I'm trying to take that data and map it to an array that exists on the global scope followed by a function to export the new data as a pdf - my issue is that the then() block is firing before the other function finishes and far before the first API call finshes. `
let fireWatson = async () => {
let watsonClassifed = []
let watsonCallIndex = 0;
let returnedArr = []
for (let i = 0; i < watsonData.length; i++) {
let params = {
classifierId: '***********',
collection: watsonData[i]
}
naturalLanguageClassifier.classifyCollection(params,
function (err, response) {
if (err)
console.log('error:', err);
else
console.log("data returned")
console.log(response.result.collection)
watsonClassifed.push(response.result.collection);
console.log(watsonClassifed)
})
}
}
fireWatson(watsonData).then(res =>
console.log("firing stupid callbback after data")
)
I realize this function isnt actually returning anything but is it possible to still make use of a promise without a return value or is this the main issue im hitting? Ideally - i want the then function to wait until the data is back - mapped to the global array and then outputted but this of course depends on proper synchronicity.
output:
[Done] exited with code=0 in 1.526 seconds
[Running] node "index.js"
firing stupid callbback
data returned
all my sweet sweet data
All functions in JavaScript have returns, it's just that they are implicit if you don't say return explicitly
It's always a bit tricky to mix promises with callbacks. Here is a way you can fireWatson without using any utilities.
let fireWatson = async watsonData => Promise.all(watsonData.map(collection => new Promise((resolve, reject) => {
let params = {
classifierId: '***********',
collection: collection,
}
return naturalLanguageClassifier.classifyCollection(params, function(err, response) => {
if (err) {
reject(err)
} else {
resolve(response)
}
})
})))
Of course, you can simplify this tremendously using a utility I created
const { map } = require('rubico')
let fireWatson = map(collection => new Promise((resolve, reject) => {
let params = {
classifierId: '***********',
collection: watsonData[i]
}
return naturalLanguageClassifier.classifyCollection(params, function(err, response) => {
if (err) {
reject(err)
} else {
resolve(response)
}
})
}))
turns out console.log was firing because every .then() block expects a function.
wrong:
fireWatson(watsonData).then(res =>
console.log("firing stupid callbback after data")
)
right:
fireWatson(watsonData).then(()res =>
console.log("firing stupid callbback after data")
)
export const USER_KEY = "isLoggedIn";
export const phoneVerified = () => AsyncStorage.setItem(USER_KEY, 1);
export const userInfoVerified = () => AsyncStorage.setItem(USER_KEY, 2);
I have used the above functions to store the value and the below one to get the value.
export const isSignedIn = () => {
return new Promise((resolve, reject) => {
AsyncStorage.getItem(USER_KEY)
.then(res => {
console.log("from isSignedIn : "+res); //res is showing null.
if (res !== null) {
resolve(res);
} else {
resolve(0);
}
})
.catch(err => reject(err));
});
};
Why this always returns null? I was trying async/await but still getting null. I think somehow the data is not storing.
I'm afraid you can only store strings. Please refer to this React Native AsyncStorage storing values other than strings and this https://facebook.github.io/react-native/docs/asyncstorage.html#setitem
Thanks.
As answered by #Vishu Bhardwaj AsyncStorage accepts only string. So you can use JSON.stringify() and JSON.parse() in such cases.
I was stuck with this stupid problem for almost one week, no other way that is suggested in all communities worked for me, but then I found something that is built of react-native which its setState() callback function: https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296.
so the only way that I guarantee that it's the only secure way so far is this that u use the setState() function in your promise and everything that you need to run, put them on a function and call it for the setState() callback function , this is only way you can make sure yourself that you neither get null nor never calling the function . Here I'm going to provide an example of it which this.tokeToServer() is my function which it's used as a callback function.
try {
AsyncStorage.getItem('firebase_token',(err,item) => {
if (item) {
this.setState({
firebase_token: item,
}),this.tokenToServer();
}
});
} catch (error) {
console.log("Error retrieving data" + error);
}
As presented by friend Abdu4, I had the same problem for 4 days and searching for different sites and forums. Attempts with async/await and others, even though you should use these options, the one you completed and really worked was to assign the value through setState by callback
try {
AsyncStorage.getItem('TOKEN_KEY',(err,item) => {
if (item) {
setToken({
Token: item,
});
}
});
} catch (error) {
console.log("Error retrieving data" + error);
}