Can't push object into another object, how can I change my code to work with async/await?












0















I'm having issues trying to work with api "pagination", I need to merge multiple objects into one. However, I can't seem to figure out how to do this with promises and I'm not sure how to work with async/await to get the best results.



I have a class called selly, which works with the Selly API.



getAllProducts(page = 1) {
return this.makeRequest('products', { page: page });
}
makeRequest(endpoint, params = {}) {
return axios
.get(`https://selly.gg/api/v2/${endpoint}`, {
headers: {
Authorization: `Basic ${this.genApiToken(this.apiKey, this.apiEmail)}`,
'User-Agent': `username - localhost`,
},
params: params,
})
.catch((err) => {
console.log(err);
});
}


Which worked great, until I realized I need to fetch multiple pages and combine all of the results into a single object. Here's my attempt:



app.get('/api/products', (req, res) => {
res.setHeader('Content-Type', 'application/json');
selly.getAllProducts().then((request) => {
const pages = request.headers['x-total-pages'];
let products = request.data;
if (pages > 1) {
let i = 2;
while (pages >= i) {
selly.getAllProducts(i).then((nextPageRequest) => {
nextPageRequest.data.forEach((item) => {
products.push(item);
});
});
i++;
}
}
res.send(JSON.stringify(products));
});
});


I can't seem to push nextPageRequest to products object. Obviously because res.send runs before the promise selly.getAllProducts(i) is finished.



I understand that the best optimization for this is using async and await, however I just can't get the basic concept of it, or well, at-least how would I refactor my code into using async and await.



How can I get this working?










share|improve this question

























  • Do you want the requests for the multiple pages to go out in parallel (all at once), or in serial (one only after the last is complete)?

    – CertainPerformance
    Jan 1 at 2:10











  • you actually are pushing in to products - it's just that you are also "using" products before you've pushed anything on to it - that's asynchrony at work

    – Jaromanda X
    Jan 1 at 2:12











  • @CertainPerformance I'd like to group multiple pages into one then send it out.

    – kinx
    Jan 1 at 2:12











  • But do you want to send the requests in parallel or in serial?

    – CertainPerformance
    Jan 1 at 2:13











  • One only after the last is complete.

    – kinx
    Jan 1 at 2:14
















0















I'm having issues trying to work with api "pagination", I need to merge multiple objects into one. However, I can't seem to figure out how to do this with promises and I'm not sure how to work with async/await to get the best results.



I have a class called selly, which works with the Selly API.



getAllProducts(page = 1) {
return this.makeRequest('products', { page: page });
}
makeRequest(endpoint, params = {}) {
return axios
.get(`https://selly.gg/api/v2/${endpoint}`, {
headers: {
Authorization: `Basic ${this.genApiToken(this.apiKey, this.apiEmail)}`,
'User-Agent': `username - localhost`,
},
params: params,
})
.catch((err) => {
console.log(err);
});
}


Which worked great, until I realized I need to fetch multiple pages and combine all of the results into a single object. Here's my attempt:



app.get('/api/products', (req, res) => {
res.setHeader('Content-Type', 'application/json');
selly.getAllProducts().then((request) => {
const pages = request.headers['x-total-pages'];
let products = request.data;
if (pages > 1) {
let i = 2;
while (pages >= i) {
selly.getAllProducts(i).then((nextPageRequest) => {
nextPageRequest.data.forEach((item) => {
products.push(item);
});
});
i++;
}
}
res.send(JSON.stringify(products));
});
});


I can't seem to push nextPageRequest to products object. Obviously because res.send runs before the promise selly.getAllProducts(i) is finished.



I understand that the best optimization for this is using async and await, however I just can't get the basic concept of it, or well, at-least how would I refactor my code into using async and await.



How can I get this working?










share|improve this question

























  • Do you want the requests for the multiple pages to go out in parallel (all at once), or in serial (one only after the last is complete)?

    – CertainPerformance
    Jan 1 at 2:10











  • you actually are pushing in to products - it's just that you are also "using" products before you've pushed anything on to it - that's asynchrony at work

    – Jaromanda X
    Jan 1 at 2:12











  • @CertainPerformance I'd like to group multiple pages into one then send it out.

    – kinx
    Jan 1 at 2:12











  • But do you want to send the requests in parallel or in serial?

    – CertainPerformance
    Jan 1 at 2:13











  • One only after the last is complete.

    – kinx
    Jan 1 at 2:14














0












0








0








I'm having issues trying to work with api "pagination", I need to merge multiple objects into one. However, I can't seem to figure out how to do this with promises and I'm not sure how to work with async/await to get the best results.



I have a class called selly, which works with the Selly API.



getAllProducts(page = 1) {
return this.makeRequest('products', { page: page });
}
makeRequest(endpoint, params = {}) {
return axios
.get(`https://selly.gg/api/v2/${endpoint}`, {
headers: {
Authorization: `Basic ${this.genApiToken(this.apiKey, this.apiEmail)}`,
'User-Agent': `username - localhost`,
},
params: params,
})
.catch((err) => {
console.log(err);
});
}


Which worked great, until I realized I need to fetch multiple pages and combine all of the results into a single object. Here's my attempt:



app.get('/api/products', (req, res) => {
res.setHeader('Content-Type', 'application/json');
selly.getAllProducts().then((request) => {
const pages = request.headers['x-total-pages'];
let products = request.data;
if (pages > 1) {
let i = 2;
while (pages >= i) {
selly.getAllProducts(i).then((nextPageRequest) => {
nextPageRequest.data.forEach((item) => {
products.push(item);
});
});
i++;
}
}
res.send(JSON.stringify(products));
});
});


I can't seem to push nextPageRequest to products object. Obviously because res.send runs before the promise selly.getAllProducts(i) is finished.



I understand that the best optimization for this is using async and await, however I just can't get the basic concept of it, or well, at-least how would I refactor my code into using async and await.



How can I get this working?










share|improve this question
















I'm having issues trying to work with api "pagination", I need to merge multiple objects into one. However, I can't seem to figure out how to do this with promises and I'm not sure how to work with async/await to get the best results.



I have a class called selly, which works with the Selly API.



getAllProducts(page = 1) {
return this.makeRequest('products', { page: page });
}
makeRequest(endpoint, params = {}) {
return axios
.get(`https://selly.gg/api/v2/${endpoint}`, {
headers: {
Authorization: `Basic ${this.genApiToken(this.apiKey, this.apiEmail)}`,
'User-Agent': `username - localhost`,
},
params: params,
})
.catch((err) => {
console.log(err);
});
}


Which worked great, until I realized I need to fetch multiple pages and combine all of the results into a single object. Here's my attempt:



app.get('/api/products', (req, res) => {
res.setHeader('Content-Type', 'application/json');
selly.getAllProducts().then((request) => {
const pages = request.headers['x-total-pages'];
let products = request.data;
if (pages > 1) {
let i = 2;
while (pages >= i) {
selly.getAllProducts(i).then((nextPageRequest) => {
nextPageRequest.data.forEach((item) => {
products.push(item);
});
});
i++;
}
}
res.send(JSON.stringify(products));
});
});


I can't seem to push nextPageRequest to products object. Obviously because res.send runs before the promise selly.getAllProducts(i) is finished.



I understand that the best optimization for this is using async and await, however I just can't get the basic concept of it, or well, at-least how would I refactor my code into using async and await.



How can I get this working?







javascript node.js ajax promise axios






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 1 at 2:13







kinx

















asked Jan 1 at 2:09









kinxkinx

63113




63113













  • Do you want the requests for the multiple pages to go out in parallel (all at once), or in serial (one only after the last is complete)?

    – CertainPerformance
    Jan 1 at 2:10











  • you actually are pushing in to products - it's just that you are also "using" products before you've pushed anything on to it - that's asynchrony at work

    – Jaromanda X
    Jan 1 at 2:12











  • @CertainPerformance I'd like to group multiple pages into one then send it out.

    – kinx
    Jan 1 at 2:12











  • But do you want to send the requests in parallel or in serial?

    – CertainPerformance
    Jan 1 at 2:13











  • One only after the last is complete.

    – kinx
    Jan 1 at 2:14



















  • Do you want the requests for the multiple pages to go out in parallel (all at once), or in serial (one only after the last is complete)?

    – CertainPerformance
    Jan 1 at 2:10











  • you actually are pushing in to products - it's just that you are also "using" products before you've pushed anything on to it - that's asynchrony at work

    – Jaromanda X
    Jan 1 at 2:12











  • @CertainPerformance I'd like to group multiple pages into one then send it out.

    – kinx
    Jan 1 at 2:12











  • But do you want to send the requests in parallel or in serial?

    – CertainPerformance
    Jan 1 at 2:13











  • One only after the last is complete.

    – kinx
    Jan 1 at 2:14

















Do you want the requests for the multiple pages to go out in parallel (all at once), or in serial (one only after the last is complete)?

– CertainPerformance
Jan 1 at 2:10





Do you want the requests for the multiple pages to go out in parallel (all at once), or in serial (one only after the last is complete)?

– CertainPerformance
Jan 1 at 2:10













you actually are pushing in to products - it's just that you are also "using" products before you've pushed anything on to it - that's asynchrony at work

– Jaromanda X
Jan 1 at 2:12





you actually are pushing in to products - it's just that you are also "using" products before you've pushed anything on to it - that's asynchrony at work

– Jaromanda X
Jan 1 at 2:12













@CertainPerformance I'd like to group multiple pages into one then send it out.

– kinx
Jan 1 at 2:12





@CertainPerformance I'd like to group multiple pages into one then send it out.

– kinx
Jan 1 at 2:12













But do you want to send the requests in parallel or in serial?

– CertainPerformance
Jan 1 at 2:13





But do you want to send the requests in parallel or in serial?

– CertainPerformance
Jan 1 at 2:13













One only after the last is complete.

– kinx
Jan 1 at 2:14





One only after the last is complete.

– kinx
Jan 1 at 2:14












1 Answer
1






active

oldest

votes


















0














You can make the whole app.get handler async, then await the inital request to figure out how many pages there are, then use a for loop and await additional calls of selly.getAllProducts, pushing the result to the products array. Make sure to try/catch so you can handle errors:



app.get('/api/products', async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const request = await selly.getAllProducts();
const pages = request.headers['x-total-pages'];
const products = request.data;
for (let i = 2; i <= pages; i++) {
const { data } = await selly.getAllProducts(i);
products.push(...data);
}
res.send(JSON.stringify(products));
} catch(e) {
// handle errors
}
});





share|improve this answer
























  • Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

    – kinx
    Jan 1 at 2:33






  • 1





    You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

    – CertainPerformance
    Jan 1 at 2:36











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53992630%2fcant-push-object-into-another-object-how-can-i-change-my-code-to-work-with-asy%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














You can make the whole app.get handler async, then await the inital request to figure out how many pages there are, then use a for loop and await additional calls of selly.getAllProducts, pushing the result to the products array. Make sure to try/catch so you can handle errors:



app.get('/api/products', async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const request = await selly.getAllProducts();
const pages = request.headers['x-total-pages'];
const products = request.data;
for (let i = 2; i <= pages; i++) {
const { data } = await selly.getAllProducts(i);
products.push(...data);
}
res.send(JSON.stringify(products));
} catch(e) {
// handle errors
}
});





share|improve this answer
























  • Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

    – kinx
    Jan 1 at 2:33






  • 1





    You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

    – CertainPerformance
    Jan 1 at 2:36
















0














You can make the whole app.get handler async, then await the inital request to figure out how many pages there are, then use a for loop and await additional calls of selly.getAllProducts, pushing the result to the products array. Make sure to try/catch so you can handle errors:



app.get('/api/products', async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const request = await selly.getAllProducts();
const pages = request.headers['x-total-pages'];
const products = request.data;
for (let i = 2; i <= pages; i++) {
const { data } = await selly.getAllProducts(i);
products.push(...data);
}
res.send(JSON.stringify(products));
} catch(e) {
// handle errors
}
});





share|improve this answer
























  • Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

    – kinx
    Jan 1 at 2:33






  • 1





    You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

    – CertainPerformance
    Jan 1 at 2:36














0












0








0







You can make the whole app.get handler async, then await the inital request to figure out how many pages there are, then use a for loop and await additional calls of selly.getAllProducts, pushing the result to the products array. Make sure to try/catch so you can handle errors:



app.get('/api/products', async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const request = await selly.getAllProducts();
const pages = request.headers['x-total-pages'];
const products = request.data;
for (let i = 2; i <= pages; i++) {
const { data } = await selly.getAllProducts(i);
products.push(...data);
}
res.send(JSON.stringify(products));
} catch(e) {
// handle errors
}
});





share|improve this answer













You can make the whole app.get handler async, then await the inital request to figure out how many pages there are, then use a for loop and await additional calls of selly.getAllProducts, pushing the result to the products array. Make sure to try/catch so you can handle errors:



app.get('/api/products', async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const request = await selly.getAllProducts();
const pages = request.headers['x-total-pages'];
const products = request.data;
for (let i = 2; i <= pages; i++) {
const { data } = await selly.getAllProducts(i);
products.push(...data);
}
res.send(JSON.stringify(products));
} catch(e) {
// handle errors
}
});






share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 1 at 2:19









CertainPerformanceCertainPerformance

86.8k154774




86.8k154774













  • Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

    – kinx
    Jan 1 at 2:33






  • 1





    You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

    – CertainPerformance
    Jan 1 at 2:36



















  • Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

    – kinx
    Jan 1 at 2:33






  • 1





    You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

    – CertainPerformance
    Jan 1 at 2:36

















Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

– kinx
Jan 1 at 2:33





Cool stuff here. I know this is a lot to ask for, but is it possible you can explain, or link to me guides how work with async and where to use it? Feels like every time I attempt to use these keywords, I'm doing it wrong. Love this though, thank you.

– kinx
Jan 1 at 2:33




1




1





You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

– CertainPerformance
Jan 1 at 2:36





You can make any function async, and it will return a Promise. This will allow you to use await inside - then, anywhere inside the function you're using <somePromise>.then((result) => { you can replace that with const result = await <somePromise>. Note that await isn't necessary - it's pretty simple to do the above with only Promises without async/await, await just makes the code flatter and a bit easier to read. See javascript.info/async-await

– CertainPerformance
Jan 1 at 2:36




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53992630%2fcant-push-object-into-another-object-how-can-i-change-my-code-to-work-with-asy%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas