Hello I have this async function which retrieves user profile and repositories through github api and returns them in an object.
And I want to convert this to a promise based function by using promise chaining (without any helper methods).
async function getUser(user) {
const profileResponse = await fetch(`/${user}`);
const profileData = await profileResponse.json();
const repoResponse = await fetch(`/${user}/repos`);
const reposData = await repoResponse.json();
// returning an object with profile and data
return {
profile:profileData,
repos:repoData,
};
}
//Calling the function here.
getUser("abufattah").then((res) => console.log(res));
I have managed to get it done using two helper functions and promise.all() method.
But how can I achieve the same thing by using promise chaining without any helper functions.
//Helper function 1: returns a promise with user profile data.
function getUserProfile(user) {
return fetch(`/${user}`)
.then((res) =>res.json());
}
//Helper function 2: returns a promise with user repositories data.
function getUserRepos(user) {
return fetch(`/${user}/repos?per_page=5&sort=created`)
.then((res) => res.json());
}
//Main function
function getUserWithPromise(user) {
return new Promise((resolve) => {
let profile = getUserProfile(user);
let repos = getUserRepos(user);
Promise.all([profile, repos]).then((values) => {
resolve({ profile: values[0], repos: values[1] });
});
});
}
// calling the function here
getUserWithPromise("abufattah").then((res) => console.log(res));
Hello I have this async function which retrieves user profile and repositories through github api and returns them in an object.
And I want to convert this to a promise based function by using promise chaining (without any helper methods).
async function getUser(user) {
const profileResponse = await fetch(`https://api.github./users/${user}`);
const profileData = await profileResponse.json();
const repoResponse = await fetch(`https://api.github./users/${user}/repos`);
const reposData = await repoResponse.json();
// returning an object with profile and data
return {
profile:profileData,
repos:repoData,
};
}
//Calling the function here.
getUser("abufattah").then((res) => console.log(res));
I have managed to get it done using two helper functions and promise.all() method.
But how can I achieve the same thing by using promise chaining without any helper functions.
//Helper function 1: returns a promise with user profile data.
function getUserProfile(user) {
return fetch(`https://api.github./users/${user}`)
.then((res) =>res.json());
}
//Helper function 2: returns a promise with user repositories data.
function getUserRepos(user) {
return fetch(`https://api.github./users/${user}/repos?per_page=5&sort=created`)
.then((res) => res.json());
}
//Main function
function getUserWithPromise(user) {
return new Promise((resolve) => {
let profile = getUserProfile(user);
let repos = getUserRepos(user);
Promise.all([profile, repos]).then((values) => {
resolve({ profile: values[0], repos: values[1] });
});
});
}
// calling the function here
getUserWithPromise("abufattah").then((res) => console.log(res));
Share
Improve this question
edited Feb 20, 2022 at 14:12
T.J. Crowder
1.1m200 gold badges2k silver badges2k bronze badges
asked Feb 20, 2022 at 14:09
Abu FattahAbu Fattah
331 silver badge6 bronze badges
6
-
2
Regardless of how (or whether) you do it, you'll want to handle checking
ok
onresponse
; right now, that code is falling prey to thefetch
API footgun I describe here. – T.J. Crowder Commented Feb 20, 2022 at 14:13 -
1
Your code using
Promise.all
doesn't do what your original function does, it handles the requests in parallel, but your original handled them in series. Is that intentional? – T.J. Crowder Commented Feb 20, 2022 at 14:15 -
3
Why tho…?! The explicit
new Promise
is most certainly entirely unnecessary. What problem does "using promises instead ofawait
" solve for you? – deceze ♦ Commented Feb 20, 2022 at 14:15 -
3
"I want to convert this to a promise based function" - your function is promise-based already, and it does return a promise, regardless whether you use
.then()
orawait
syntax. – Bergi Commented Feb 20, 2022 at 14:16 - 1 @T.J.Crowder no that wasnt intentional :p – Abu Fattah Commented Feb 20, 2022 at 14:54
4 Answers
Reset to default 3Transformation of async
/await
syntax to .then()
calls is quite mechanical, especially if it doesn't involve any control flow syntax (loops or conditionals):
function getUser(user) {
return fetch(`https://api.github./users/${user}`).then(profileResponse => {
return profileResponse.json().then(profileData => {
return fetch(`https://api.github./users/${user}/repos`).then(repoResponse => {
return repoResponse.json().then(reposData => {
// returning an object with profile and data
return {
profile:profileData,
repos:reposData,
};
});
});
});
});
}
But there's no good reason to write code like that. If it's just that your target environment does not support async
/await
, let a transpiler do the transformation.
You can:
//Main function
function getUserWithPromise(user) {
return Promise.all([
fetch(`https://api.github./users/${user}`).then((res) =>res.json()),
fetch(`https://api.github./users/${user}/repos?per_page=5&sort=created`).then((res) => res.json())
]).then(([result1, result2]) => ({ profile: result1, repos: result2 }));
}
// calling the function here
getUserWithPromise("abufattah").then((res) => console.log(res));
Chain:
function getUserWithPromise(user) {
return fetch(`https://api.github./users/${user}`)
.then((res) => {
return fetch(`https://api.github./users/${user}/repos?per_page=5&sort=created`).then((fetch2Result) => ([res.json(), fetch2Result.json()]))
}).then(([result1, result2]) => ({ profile: result1, repos: result2 }))
}
// calling the function here
getUserWithPromise("abufattah").then((res) => console.log(res));
Try to use babel-plugin-transform-async-to-promises, it seems to have 400,135 downloads per week, but you should use it carefully as it is not maintained for several years, before you use it, perhaps you should have a look at its issues first.
Simple:
const getUser = user => Promise
.all([
fetch(`https://api.github./users/${user}`).then(res => res.json()),
fetch(`https://api.github./users/${user}/repos`).then(res => res.json()),
])
.then(([profile, repos]) => ({profile, repos}));
That async/await is the most crappiest anti-pattern added to the JS. Don't use them, instead learn how to use promises correctly.