I am having issue with getting my axios request to work. I am following pattern shown me in one of the Udemy courses. Interesting thing is that I can console.log data, but I can't return data, and save it to a variable. Any help would be appreciated.
Have a nice day!
const get = async () => {
const res = await axios.get(
"https://www.themealdb.com/api/json/v1/1/list.php?i=list"
);
return res;
};
async means your function returns an promise. Thats a basic fact
const get = async () => {
const res = await axios.get(
"https://www.themealdb.com/api/json/v1/1/list.php?i=list"
);
return res;
};
get().then(result => {
console.log(result);
})
Read about it: https://javascript.info/async-await
However you do not need async in this case because axios is already returning an promise
const get = () => axios.get("https://www.themealdb.com/api/json/v1/1/list.php?i=list")
You should return res.data
import axios from 'axios';
const get = async () => {
const res = await axios.get(
"https://www.themealdb.com/api/json/v1/1/list.php?i=list"
);
return res.data;
};
const print = async()=>{
const resp = await get();
console.log(resp);
}
print();
Related
I have API on Node server returning JSON like this when called:
{"result":[{"ProductID":1,"ProductName":"iPhone10","ProductDescription":"Latest smartphone from Apple","ProductQuantity":100}]}
I'm trying to display all of that information to user using fetch API with React but no matter what my call returns undefined. Here is my React code:
const [products, setProducts] = useState({})
async function getProducts() {
await fetch(`http://127.0.0.1:5000/listProducts`)
.then(response => response.json())
.then(response=>{
setProducts({products:response.result})
console.log(response.result);
products.map(products =>
<h1>{products.ProductName}</h1>
<h1>{products.ProductDescription}</h1>
)
})
.catch(err=>console.error(err))
}
Function getProducts() is called once when page is loaded. What I'm doing wrong? Thanks in advance.
Try this it will work
const handleFetchData = async () => {
const response = await fetch(`https://api.unsplash.com/photos/random?client_id=${process.env.NEXT_PUBLIC_UNSPLASH_API_ACCESS_KEY}`);
const data = await response.json();
console.log(data);
}
useEffect(() => {
handleFetchData();
},[])
Your function is doing it wrong :
The name should be getAndSetProducts or even setProducts / initProducts because it returns a Promise<void> since you don't actually return anything ;
You're setting inside products an object { products: Product[] }, I think you want only Product[] (an array of Products) else you'll have to get products by doing products.products ;
The map is useless, since you don't do anything with the map response, plus the variable products in the map overwrite the one imported (may cause some errors later).
Try to do :
const [products, setProducts] = useState([]); // Array instead of object
async function initProducts() {
await fetch(`http://127.0.0.1:5000/listProducts`)
.then(response => response.json())
.then(response => {
setProducts(response.result);
console.log(response.result);
)
.catch(err => console.error(err));
}
function getProductsHtml() {
return products.map(product =>
<h1>{product.ProductName}</h1>
<h1>{product.ProductDescription}</h1>
);
}
You can call initProducts when component initialize and return getProductsHtml inside your jsx render.
Try this...
const [products, setProducts] = useState({})
React.useEffect(() => {
const fetchData = async () => {
const result = await fetch('http://127.0.0.1:5000/listProducts')
// console log here to determine how to set products
console.log(result)
setProducts(result)
}
fetchData()
}, [])
React.useEffect(() => {
if (!!products) {
// here you could access products!
}
}, [products])
if (!products) return null
return products.map((product) => (
<>
<h1>{products.ProductName}</h1>
<h1>{products.ProductDescription}</h1>
</>
))
If you are using Async, then you can use response.status as shown below
const response = await fetch("URL", {
body:BODY_DATA,
method:'POST',
headers: { "Content-Type": "application/json"
});
if(response.status === 200){
// Complete your action
} else {
// Show error
}
you can't use async await with .then() you should only use async await or .then() only
I am trying to load data from firebase by calling a function in which it filters data and returns them.
When I call this function in my main function, it returns "undefined". I know the data is there (console.log(postsArray)) prints the data but I guess the return executes before data is loaded.
What am I doing wrong?
calling_Function_in_Main = async () => {
const data = await FirebaseData ();
console.log(data);
};
FirebaseData is the function that I call in my main function to load data and to return them
let postsArrays=[];
const FirebaseData = async () => {
const getViewableLink = async (link) => { //some function };
const loadData = async () => {
const database = firebase.database();
const data = database.ref();
const loadProfile = data
.child('Posts')
.orderByChild('Active')
.equalTo(true)
.once('value', function gotData(data) {
Object.values(readInfo).forEach(async (element) => {
element.Option1Link = await getViewableLink(
preLink + element.Option1Link,
);
postsArray.push(element);
}
});
})
.catch((error) => {
console.log(error);
}
})
.then((postsArray) => {
console.log(postsArray);
return postsArray;
});
};
await loadData();
};
export default FirebaseSwipeData;
You can't use foreach with async/await because It is not asynchronous. It is blocking.
you have 2 ways to fix this:
1- Reading in sequence: you can use for...of loop
for(const element of Object.values(readInfo)) {
element.Option1Link = await getViewableLink(
preLink + element.Option1Link,
);
postsArray.push(element);
}
2- Reading in parallel: you can use Promise.all
await Promise.all(Object.values(readInfo).map(async (element) => {
element.Option1Link = await getViewableLink(
preLink + element.Option1Link,
);
postsArray.push(element);
}));
Hope that solves the problem, for you
Request:
async await for this line: fetch(url).then(resp => resp.json())
So there shouldn't be any .then() calls anymore!
The original code:
const urls = [
'https://jsonplaceholder.typicode.com/users',
'https://jsonplaceholder.typicode.com/posts',
'https://jsonplaceholder.typicode.com/albums'
]
const getData = async function() {
const [ users, posts, albums ] = await Promise.all(urls.map(url =>
fetch(url).then(resp => resp.json())
));
console.log('users', users);
console.log('posta', posts);
console.log('albums', albums);
}
getData();
What i try in my JS:
const [ users, posts, albums ] = await Promise.all(urls.map
(url=>
resp = await fetch(url);
data = await resp.json();
));
I want the output is as same as the original code
Your function returns nothing, and is not marked async (which is required from any function using await). Furthermore, it's not cool to not declare variables.
const [users, posts, albums] = await Promise.all(urls.map(async url => {
const resp = await fetch(url);
const data = await resp.json();
return data;
}));
EDIT: also, what guest271314 said - need curlies now that the inner function is not a simple expression.
I use fetch to get data for each element of an array. Those values are pushed into an array and I want to return the max of those values once all values are fetched.
For that I used a promise:
async function init() {
await maxWaste(nut0Codes).then(response => {
console.log(response);
});
}
function maxWaste(nutCodes) {
return new Promise(resolve => {
let waste = [];
nutCodes.forEach((element) => {
let query = queryMaxWaste(element);
fetch(address + encodeURIComponent(query))
.then(response => {
return response.json();
})
.then(response => {
waste.push(response.results.bindings[0].wasteGeneration.value);
console.log(waste);
});
});
let maxWaste = Math.max(waste);
resolve(maxWaste);
});
}
I am not sure where my mistake is but the resolve happens before the fetch is done :
I receive the zero from the console.log(response) and I don't know why it is not working.
Any advice would be appreciated!
If you're going to write code that uses async, you should actually leverage async. If this needs to be run synchronously-ish, you can await within a for loop. If you want them all to run simultaneously, use a map and Promise.all.
async function init() {
const response = await maxWaste(nut0Codes);
console.log(response);
}
async function maxWaste(nutCode) {
const waste = [];
for (const element in nutCode) {
const query = queryMaxWaste(element);
const response = await fetch(address + encodeURIComponent(query));
const json = await response.json();
waste.push(json.results.bindings[0].wasteGeneration.value);
console.log(waste);
}
const maxWaste = Math.max(waste);
return maxWaste;
}
You could also try writing it like this so that you don't wait for each response to complete before running the next fetch:
async function init() {
const response = await maxWaste(nut0Codes);
console.log(response);
}
async function maxWaste(nutCode) {
const waste = await Promise.all(nutCode.map(async element => {
const query = queryMaxWaste(element);
const response = await fetch(address + encodeURIComponent(query));
const json = await response.json();
return json.results.bindings[0].wasteGeneration.value;
}));
return Math.max(waste);
}
I got unexpected identifier but not sure what is the mistake. I'm using fetch which is already a promise.
async getUsers = () => {
const resp = await fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
return resp
}
getUsers().then(users => console.log(users))
Notice the position of the async keyword:
Not:
async getUsers = () => {
But:
getUsers = async () => {
Run:
getUsers = async () => {
const resp = await fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
return resp;
};
getUsers().then(users => console.log(users))
As per comments:
Should I chain then() in getUsers()? async/await suppose to eliminate then() am I right?
Yes, you can await any Promise. Or use both .then() sometimes and await at others (like does the code above). But you could just use async/await as well.
The example below uses no .then():
getUsers = async () => {
const resp = await fetch('https://jsonplaceholder.typicode.com/posts/1')
return resp.json();
};
(async () => {
// notice to use the await keyword, the code must be wrapped in an async function
const users = await getUsers();
console.log(users);
})();
Aside from the typo in the async word pointed by #acdcjunior, you're mixing async / await with the usual promise handling (.then()) which is not wrong but kind of defeats the point. Using only async / await would look like:
const getUsers = async () => {
const resp = await fetch('https://jsonplaceholder.typicode.com/posts/1');
return resp.json();
}
async function fetchUsers() {
try {
const users = await getUsers();
console.log(users);
} catch(err) {
console.log(err);
}
}
fetchUsers();
you have the syntax wrong:
const getusers = async () => {
...
}
const is optional
Your syntax of declaring your function is wrong, here's some explanation.
If getUsers is a method of a react component class the syntax should be :
getUsers = async () => {
const resp = await fetch(
'https://jsonplaceholder.typicode.com/posts/1'
).then(response => response.json());
return resp;
};
or :
async getUsers() {
const resp = await fetch(
'https://jsonplaceholder.typicode.com/posts/1'
).then(response => response.json());
return resp;
};
If it's outside of a react component class or in a stateless arrow function component you can use this syntax :
const getUsers = async () => {
const resp = await fetch(
'https://jsonplaceholder.typicode.com/posts/1'
).then(response => response.json());
return resp;
};
const getUsers = async () => {
try {
const resp = await fetch('https://jsonplaceholder.typicode.com/posts/1');
return resp.json();
} catch(e) {
console.error(e)
}
}
(async () => {
const users = await getUsers();
console.log(users)
})()
Use this, and run