How to make fetch promise resolve without using .then syntax? - javascript

First things first, I made sure to write a quick demo of the issue I'm talking about here https://codesandbox.io/s/exciting-swirles-7cs3s
But essentially, using the isomorphic-fetch library, I'm running into an issue where I can't really get the value, or you might say, resolution, of the fetch() function.
import fetch from "isomorphic-fetch";
async function test() {
return await fetch("https://google.com", { mode: "no-cors" });
}
let t = test();
console.log(t);
The outcome of which is
Now I've also considered the other way of using fetch() like this
fetch("https://google.com", { mode: "no-cors" })
.then(response => response.text())
.then(data => console.log(data));
which actually delivers a string, but I prefer doing it the first way, if possible? It's also very possible I'm not using fetch correctly.

Try it like this:
import fetch from "isomorphic-fetch";
async function test() {
const response = await fetch("https://google.com", { mode: "no-cors" });
return response.text();
}
async function main() {
let t = await test();
console.log(t);
}
main();
You need to await the promise, and that means you need an async function.

fetch will return a promise, not a string. In your second example you call .text() on it. You will have to do something similar in asyc/await

Use t.then(res => console.log(res)); it will return response object.
As you have async function test and you are not awaiting it like await test() so it will return promise.
As per your comment you should be using await test(). But you can only use await inside async so I suggest to use wrapper function like below.
import fetch from "isomorphic-fetch";
async function test() {
return await fetch("https://google.com", { mode: "no-cors" });
}
async function wrapper() {
let t = await test();
console.log(t.text());
}
wrapper();

Related

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);
})()

Returning promise instead of data

In the following code I wrote to get data from an API, I am getting promises as an output instead of data. What am I missing? Can someone please help?
const axios = require('axios');
const ageFinder = async (userName) => {
try {
let userDetails =await axios.get(`https://hacker-news.firebaseio.com/v0/user/${userName}.json`)
let user =userDetails.data
return user
} catch(err) {
console.log(err.message)
}
}
console.log(ageFinder("someUser"))
As per the MDN page on async functions, any function declared async returns a promise, which resolves whatever the function returns or rejects with an error, if any is encountered within the function (see "Return Value" section of page linked above).
So you will need to put your function call ageFinder("someUser") in another async function and await its result before logging, or you may use .then().
An async function always returns a promise. To use it you need to await it in another async function. If you do not want to await in another async function you may use it with the alternative then method. For example:
ageFinder("someUser")
.then((response) => {
console.log(response);
}).
.catch((err) => {
console.log(err);
});

How do I pass a parameter to API request 2, which I receive from API response 1 in react

My 2 API calls happen to be at the same time, where the response of API1 is to be sent as a request parameter to API2. But, the value goes as undefined because it isn't fetched till that time. Is there any way this can be solved in react.
There are multiple ways to solve this problem, I will explain one of the latest as well most sought after ways of solving the problem.
I am sure you would have heard of async/await in JavaScript, if you haven't I would suggest you to go through an MDN document around the topic.
There are 2 keywords here, async && await, let's see each of them one by one.
Async
Adding async before any function means one simple thing, instead of returning normal values, now the function will return a Promise
For example,
async function fetchData() {
return ('some data from fetch call')
}
If you run the above function in your console simply by fetchData(). You'd see that instead of returning the string value, this function interestingly returns a Promise.
So in a nutshell async ensures that the function returns a promise, and wraps non-promises in it.
Await
I am sure by now, you would have guessed why we use keyword await in addition to async, simply because the keyword await makes JavaScript wait until that promise (returned by the async function) settles and returns its result.
Now coming on to how could you use this to solve your issue, follow the below code snippet.
async function getUserData(){
//make first request
let response = await fetch('/api/user.json');
let user = await response.json();
//using data from first request make second request/call
let gitResponse = await fetch(`https://api.github.com/users/${user.name}`)
let githubUser = await gitResponse.json()
// show the avatar
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
// wait 3 seconds
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();
return githubUser;
}
As you can see the above code is quite easy to read and understand. Also refer to THIS document for more information on async/await keyword in JavaScript.
Asyn/await solves your problem:
const requests = async () =>{
const response1 = await fetch("api1")
const result1 = await response1.json()
// Now you have result from api1 you might use it for body of api2 for exmaple
const response2 = await fetch("api2", {method: "POST", body: result1})
const result2 = await response1.json()
}
If you're using react hooks, you can use a Promise to chain your API calls in useEffect
useEffect(() => {
fetchAPI1().then(fetchAPI2)
}, [])
relevant Dan Abramov
fetch(api1_url).then(response => {
fetch(api2_url, {
method: "POST",
body: response
})
.then(response2 => {
console.log(response2)
})
})
})
.catch(function (error) {
console.log(error)
});
or if using axios
axios.post(api1_url, {
paramName: 'paramValue'
})
.then(response1 => {
axios.post(api12_url, {
paramName: response1.value
})
.then(response2 => {
console.log(response2)
})
})
.catch(function (error) {
console.log(error);
});

Node JS: Can't Return Data and Export from Async Axios Function

This is an incredibly simple example taken from the Axios documentation and various blog posts:
All I'm trying to do is return data from an async function and call it elsewhere:
In file: axios.js:
const axios = require("axios");
async function getJson() {
const url = "https://jsonplaceholder.typicode.com/posts/1";
const response = await axios.get(url);
const data = response.data;
return data;
}
console.log(getJson());
Then I run node axios.js
But instead of logging out the actual Json data from the api as expected, its logging the Promise with:
Promise { <pending> }
This very simply example is taken from this post: https://scotch.io/tutorials/asynchronous-javascript-using-async-await
(Above the error handling section).
Is there something fundamental that I'm misunderstanding here? Sorry this is incredibly frustrating, I have read several blog posts and stack overflow articles, and nothing explains this or provides an answer.
For now I'm doing this one file but later the idea is simply to import and call this function in another file and get the data returned by the function.
you need to await for the async request, for example,
import { getJson } from '../file';
async function printJSON() {
const jsonData = await getJson();
console.log(jsonData);
}
because here getJSON is an async function.
Your function is async which means it returns a Promise, as you've found out but clearly are not expecting.
You need to await the function call. E.g.
console.log(await getJson());
Or, you could also do:
getJson().then(json => {
console.log(json);
});
Simple Example:
const getAppointment = (appointmentId) => {
return axios.get("example.com");
};
getAppointment(123).then(response => {
if (response.status === 200) {
console.log(response.data); // Do what you want with the JSON
}
});

Using async requires async function, but my function is async

I'm adapting a library that uses callback to use Promises. It's working when I use then(), but it doesn't work when I use await.
> dbc.solve
[AsyncFunction]
> await dbc.solve(img)
await dbc.solve(img)
^^^^^
SyntaxError: await is only valid in async function
The code for dbc.solve is:
module.exports = DeathByCaptcha = (function() {
function DeathByCaptcha(username, password, endpoint) {
...
}
DeathByCaptcha.prototype.solve = async function(img) {
return new Promise(
function(resolve, reject) {
...
}
);
};
})();
I believe this has something with the fact solve is member of prototype, but I couldn't find any information about it. I found that node didn't always supported async await for class methods, so I upgraded from node 7, now I'm using node 9.4.0.
You don't read that error message right: the problem isn't the function you're calling but the function you're in.
You may do
(async function(){
await dbc.solve(img);
// more code here or the await is useless
})();
Note that this trick should soon enough not be needed anymore in node's REPL: https://github.com/nodejs/node/issues/13209
SyntaxError: await is only valid in async function - just like the error tells you, you may only use await inside a function which is marked as async. So you cannot use the await keyword anywhere else.
https://basarat.gitbooks.io/typescript/docs/async-await.html
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-7.html
examples:
function test() {
await myOtherFunction() // NOT working
}
async function test() {
await myOtherFunction() //working
}
You can also make anonymous callback functions async:
myMethod().then(async () => {
await myAsyncCall()
})
The await operator can only be used in an async function.
You may not need async await abstraction really. Why don't you just simply promisify dbc.solve() function with a promisifier like;
function promisify(f){
return data => new Promise((v,x) => f(data, (err, id, sol) => err ? x(err) : v({i:id, s:solution})));
}
You will have a promisified version of your dbc.solve() and if it doesn't fire an error you will be returned with an object like {i:id, s: solution} at it's then stage.

Categories