Fetch results undefined on first call [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I have the following Vue methods. When clicking on the edit button, onEditUserPermissions is called. That function also fetches this.fetchUserPermissions. The request does finish, and a response is received.
methods:{
onEditUserPermissions(item){
this.userCheckbox = true
let user = item.id
this.selectedUser = item.id;
this.fetchUserPermissions(user)
for (let x of this.assignedUserPermissions){
console.log('assigned',x.id)
this.selectedUserItems.push(x.id)
}
this.editedIndex = 'users'
this.dialog = true
},
fetchUserPermissions(user){
this.$axios.get('/permissions/assigned/user/'+user)
.then(res => {
this.assignedUserPermissions = res.data
})
},
}
When I first click, the for of loop doesnt work, it doesnt iterate, however, when clicked again, it works. I may be too close to the project but can anyone tell why?

You need to wait for the http promise to resolve before attempting to access the data. It works the second time because then it uses the result from the first fetch.
First, you need to return the promise from fetchUserPermissions, and then you need to wait for that promise in onEditUserPermissions:
methods: {
async onEditUserPermissions(item){ // `async` keyword
this.userCheckbox = true
let user = item.id
this.selectedUser = item.id;
await this.fetchUserPermissions(user); // awaiting the promise
for (let x of this.assignedUserPermissions){
console.log('assigned',x.id)
this.selectedUserItems.push(x.id)
}
this.editedIndex = 'users';
this.dialog = true
}
fetchUserPermissions(user){
return this.$axios.get('/permissions/assigned/user/'+user) // return the promise
.then(res => {
this.assignedUserPermissions = res.data
})
},
}

Related

Returning Data from a forEach inside a Promise [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I'm having issues returning a created Object the code is below:
Within the Promise.allSettled, I eventually get the results which I loop over and push each array to an object (This creates the object fine), when I try and return that said object, it's empty.
I think it's because my promise hasn't settled, I've tried doing:
Promise.resolve(returnedData) then returning it, and even .then(results => results).
What am I missing? I think I've looked at this for so long there's something clear as day I'm missing.
const getProductData = () => {
debugger;
const productIds = [];
const returnedData = [];
const customerLocation = getCustomerLocation();
productdataItems.forEach((product) => {
productIds.push(
product
.querySelector('[data-test-id="product-card-code"]')
.innerHTML.replace(/[^0-9]/g, ''),
);
});
const items = productIds.map((product) => ({
productCode: product,
quantity: 1,
}));
// Load in products for other steps
const promises = [];
productIds.forEach((sku) => {
promises.push(getProduct(sku));
});
Promise.allSettled(promises).then((results) => {
// Stock requires location data.
if (customerLocation) {
getEligibility(items, customerLocation).then((eligibility) => {
getStock([customerLocation.collectionBranchId], productIds).then(
(stock) => {
results.forEach((result, i) => {
if (result.value.product) {
returnedData.push({
Product: result.value.product,
Eligibility: eligibility[i],
Stock: stock[i].quantity,
ProductMarkup: productdataItems,
PostCode: customerLocation.deliveryPostcode,
});
}
});
},
);
});
}
});
return returnedData;
};
returnedData is outside the promise.allSettled. So it is getting returned before the Promise.allSettled completes and hence it is empty.
What you should be doing is moving the return of returnData inside Promises
return Promise.allSettled(promises).then((results) => {
... ...
return returnData;
}
The getProductData needs to be a async method that returns a promise result.

Getting an object instead of a boolean value [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I have an async function that checks the permission status in a device.
This is the function:
notificationsAllowed = async () => {
const allowed = await requestNotifications(['alert', 'sound']).then((res) => {
if (res.status == "granted") {
return true;
}
return false;
});
return allowed;
}
allowed is boolean, but when I try to use this function (for example, to set a switch to true or false) I get an object for some reason.
This is how I try to use it:
const allowed = NotificationsManager.getInstance().notificationsAllowed().then((res) => {
return res;
});
const [isEnabled, setIsEnabled] = useState(allowed);
It seems like allowed is of type Promise<boolean> but I can't use async await because it is inside a functional component.
You should use useEffect for something like this.
const [isEnabled, setIsEnabled] = useState(false);
useEffect(() => {
NotificationsManager.getInstance().notificationsAllowed().then((res) => {
setIsEnabled(res);
});
}, []);
This is not how async functions or await work. Normally, with Promises (like requestNotifications), you run it, it does its work in the background and then it runs the .then() function when it's done (at some point in the future).
await does what it says, and waits for the Promise to resolve/finish before continuing on. You don't need .then() here, since you are waiting for it to finish in a different way.
notificationsAllowed = async () => {
const allowed = await requestNotifications(['alert', 'sound']);
return allowed.status === "granted"
};
But now notificationsAllowed is an async function. So you either need to use .then() which runs it in the background or use await to wait for notificationsAllowed to complete.
const allowed = await NotificationsManager.getInstance().notificationsAllowed();
const [isEnabled, setIsEnabled] = useState(allowed);
Or you need to use a callback, which will run at some point in the future and not let you return a value:
NotificationsManager.getInstance().notificationsAllowed().then(allowed => {
const [isEnabled, setIsEnabled] = useState(allowed);
});

javascript/vue.js async/await and .then (promise) not waiting until completion of fetch in login function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I build a login function and check the credentials on my backend-server. I have to wait for the response of the server. I have used an official guide to es7-async-await.js, but it does not work. I have tried everything that async/await and promises give, but it does not work at all. I read all the posts regarding this issue. What am I doing wrong?
My function:
async getCredentials(pUser, pCipher) {
var url = new URL(serviceURL);
var params = {
user: pUser,
p: pCipher
}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
// await response of fetch call
let response = await fetch(url, {
method: 'get',
headers: { }
});
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
return data;
},
my function call:
this.getCredentials(this.input.username, cipher)
.then(data => this.checkResponse = data.items)
.catch(reason => console.log(reason.message))
console.log("data: ->>>> " ,this.checkResponse);
the result:
data is always empty because the function does not wait
can you put the console.log in the .then?. Is printing something?. If you do a console.log when the data is not received will not print anything.
this.getCredentials(this.input.username, cipher)
.then(data =>
{
this.checkResponse = data.items
console.log("data: ->>>> " ,this.checkResponse);
})
.catch(reason => console.log(reason.message))

Returning the result from nested .then to another function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I can't work out how to return the nested .then methods, and resolve the value to the function that called it?
I can print it, at the deepest level of the last .then(), but I would like to print the returned value in the event listener.
connectedCallback () {
this.input.addEventListener('input', event => {
this.search(this.input.value)
})
}
search (str) {
let searchResult = window.fetch(`http://localhost:3000/api/?q=${str}`)
.then(result => {
return result.json()
.then(result => {
return result
})
})
}
}
Use async/await to await the promise result in the event listener. You can also simplify your promise chain considerably:
connectedCallback() {
this.input.addEventListener("input", async event => {
const result = await this.search(this.input.value);
console.log(result);
});
},
search(str) {
return window
.fetch(`http://localhost:3000/api/?q=${str}`)
.then(result => result.json());
}
I would recommend reading up on promises and getting familiar with how they work.

Consuming an Api and returning a value inside of a then [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I'm consuming an API that returns a famous quote, i wanna grab that quote and consume another api to search for an image related to that quote, but when i make a function that returns the famous quote and call it, it always returns Undefined.
I've tried with promises and async and even timeouts but i haven't been able to return anything.
This is file generate.js
const unirest = require('unirest');
exports.getQuote = function() {
unirest.get("https://andruxnet-random-famous-quotes.p.rapidapi.com/?cat=movies&count=1")
.header("X-RapidAPI-Host", "andruxnet-random-famous-quotes.p.rapidapi.com")
.header("X-RapidAPI-Key", "api-key").then(async (response) => {
const {quote} = await response.body[0];
return (quote);
});
}
quote.js
const middleware = require('../middleware/generate');
router.get('/look',(req,res) => {
async function call() {
const quote = await middleware.getQuote()
setTimeout(function() {
console.log('quote has: ', quote);
}, 5000);
}
call();
res.status(200).json({
message: 'its working'
});
});
When i call generate.js the output is the quote, but when i call it form the quote.js the output is undefined
Try returning the http.get:
exports.getQuote = function () {
return unirest.get("https://andruxnet-random-famous-quotes.p.rapidapi.com/?cat=movies&count=1")
.header("X-RapidAPI-Host", "andruxnet-random-famous-quotes.p.rapidapi.com")
.header("X-RapidAPI-Key", "api-key").then(async (response) => {
const { quote } = await response.body[0];
return (quote);
});
};

Categories

Resources