Why is response.json() returning a promise? - javascript

I have this JavaScript fetch function
async getAllExpensesByUser() {
let reponse = await fetch("router.php/getAll");
console.log(reponse.json());
}
also tried
getAllExpensesByUser = async () => {
const response = await fetch("router.php/getAll");
if (response.ok) {
const jsonValue = await response.json();
return Promise.resolve(jsonValue);
} else {
return Promise.reject("*** PHP file not found");
}
};
my router.php file has this code
$data = $expensesController->getExpensesForUser($_SESSION['userid']);
echo json_encode($data);
but response.json() is returning PromiseĀ {<pending>} and the result I need is inside of [[PromiseResult]]

response.json() returns a Promise because this method takes a Response stream and reads it to completion, and this is an asynchronous process. You can find more information about it in the specification
What you need is just wait when the process of reading stream ends, for this purposes you can use await as well
async getAllExpensesByUser() {
let reponse = await fetch("router.php/getAll");
let object = await response.json();
return object
}
...
const userExpenses = await getAllExpensesByUser()
console.log(userExpenses)
...

As pointed out by Yousaf, both fetch and Body.json() return promises. To wait for both the fetch and Body.json calls to resolve before continuing, you simply need to update your code like this:
async getAllExpensesByUser() {
let reponse = await fetch("router.php/getAll");
let object = await response.json();
console.log(object);
return object;//If needed, see the comment by Emiel
}

Related

pending promise inside async/await

I wast trying to fetch some data in componentDidMount and then set it to state, wrote an async await function for the same. But if i was trying to set the state with the values right after await, the value was getting set to a pending promise but console logging would give the correct output.
For that reason i called the getData().then() to set the data, why it was giving pending promise can someone clear the concept out here?
componentDidMount() {
async function getData() {
const baseUrl = `https://........`;
const response = await fetch(baseUrl);
if (response.status === 200) {
const json = await response.json();
const { data } = json;
//console.log(data) =>correct output
return data;
}
return null;
}
getData().then(data => {
this.setState({ names: data });
});
}
You can simply do it like that:
componentDidMount() {
const baseUrl = `https://........`;
fetch(baseUrl)
.then((response) => response.json())
.then(result => {
this.setState({ names: result.data});
});
}
getData is an async function that you syncronize your fetch call inside. So it returns a promise. You're console logging inside that function after response fetched. So it logs the data.
You can think it as Fetch function that you use, you're awaiting it because it's a async function and you should await for the response. It's the same for the getData too. No matter how you wait, use then or await.

javascript how to initialized a async await function into a variable

i am a beginner in javascript async await function. I have tried to make a asynchronous request in my backend and i want it to initialized in my variable but when I tried to log my variable, it gives me a promise and not a value. When i also tried to put an await. It gives me error.
Here is what I've done:
const getActivityContestApi = async () => {
try {
const response = await fetch(
`${getDjangoApiHost()}/api/events/event_activity_contests/`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
return data;
} catch(error) {
console.log(error)
}
}
The function above is my asynchronous function, I want this to be stored in a variable like this:
const test_variable = getActivityContestApi();
console.log(test_variable);
this code gives me a promise. I want the actual variable so I tried to put await like this:
const test_variable = await getActivityContestApi();
console.log(test_variable);
this gives me error in react. please help.
await is only allowed inside async function.
const test_variable = await getActivityContestApi();
you can only use this statement inside another async function.
asyncFunction will return a promise. So if you just want get result, maybe you can use then
getActivityContestApi().then((resolve,reject)=>{
let test_variable = resolve;
console.log(test_variable);
})
await can't exist outside of async function. Here is what you need to do:
;(async () => {
const test_variable = await getActivityContestApi();
console.log(test_veriable);
})()

Why don't both functions log the same result?

The 1st example logs the resolved value of the promise from the fetch.
The 2nd example logs the pending promise object to the console which I then have to .then((res) => {console.log(res)}) to get the resolved value.
I'm using async functions so I thought both examples were equivalent...?
I have not shown my API key but it works when I use it in the code.
1st Example:
const apiKey = 'somekey';
const city = 'Berlin'
const getWeather = async (cityArg, apiKeyArg) => {
let city = cityArg;
let apiKey = apiKeyArg;
try{
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`);
if(response.ok) {
let jsonResponse = await response.json();
console.log(jsonResponse);
//return jsonResponse;
}
} catch(error) {
console.log(error);
}
}
getWeather(city, apiKey);
//console.log(getWeather(city, apiKey));
2nd Example:
const apiKey = 'somekey';
const city = 'Berlin'
const getWeather = async (cityArg, apiKeyArg) => {
let city = cityArg;
let apiKey = apiKeyArg;
try{
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`);
if(response.ok) {
let jsonResponse = await response.json();
//console.log(jsonResponse);
return jsonResponse;
}
} catch(error) {
console.log(error);
}
}
//getWeather(city, apiKey);
console.log(getWeather(city, apiKey));
The reason is that you are awaiting inside that async function, but not in the console.log at the bottom.
Anything outside of that async is going to continue on running as normal. So the console.log(getWeather(city, apiKey) keeps running even though that function has not gotten a response yet. There are a few solutions. First, you could await getWeather, which requires wrapping it in a function.
await function secondFunc(){
console.log(await getWeather(city, apiKey));
}
secondFunc();
In my opinion, the better way is to use .then. I almost always use it, it is cleaner and more logical to me. Don't forget that you can chain promise statements.
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`)
.then(response => response.json())
.then((response)=>{
console.log(response);
//Other code to do stuff with the response
})
.catch((error)=>{
console.log(error);
});
Another way to think of it is that the getWeather is Async, which will wait for a response, and return a promise in the meanwhile. But console.log is not async. So console.log keeps running as usual, but it has only recieved a Promise from getWeather, because that function is not resolved.
Hope that is clear. If you don't quite understand, let me know and I will do my best to explain further.
async functions return promises and since console.log isn't an async function it won't wait for getWeather() to resolve and will just log pending
hope that clears it up
id recommend just using .then()
//you could do
getWeather(city,ApiKey).then((response) =>{console.log(response));
hope that was helpful

javascript get Json data with fetch

I'm pretty noob in js. What I want to do is to send a get request to my server and receive a json. I can do this by fetch however, it returns a promise which is not suitable for me since I need to pass the received json to another function. Is there any way to get rid of promise? if not any alternative solution? I searched a lot but found no proper solution.
here's my function:
function fetchAndConvertData(path) {
return fetch(path).then(response =>
response.json().then(data => ({
data: data,
status: response.status
})
).then(async res => {
return res.data
}));
}
You can simply write :
async function fetchAndConvertData(path) {
const response = await fetch(path);
const data = await response.json();
return { // This is a Promise because async functions always return a Promise
data,
status: response.status
}
}
(async () => {
const result = await fetchAndConvertData("some/path/here");
console.log(result)
})();

Unable to extract single value from Json object only getting [Object promise] from API

First of I'm really new to Javascript and programming in general and
This is a small part of code that is suppose to take the Json object filter it to the single string "poster_path" in the array and then send out an alert and console log it.
Now on the console log I get the desired string but the alert gives an "[Object promise]" instead of the string
async function getposter()
{
let response = await fetch('https://api.themoviedb.org/3/discover/movie?api_key=XXXXX&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1');
let poster = await response.json()
.then(poster => console.log(poster.results[0].poster_path));
return poster
}
alert(getposter())
getposter() is a promise, you need to await them to resolver before use.
An better example of how you can use or handle with your request is the code below:
async function getposter() {
const response = await fetch(
'https://api.themoviedb.org/3/discover/movie?api_key=XXXXX&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1'
);
const poster = await response.json()
const { poster_path } = poster.results[0];
return poster_path
}
(async () => {
try {
alert(await getposter());
} catch (error) {
alert(error.message);
}
})();

Categories