JavaScript: Returning array from recursive function












1















I have made a class which builds some data from api:



const http = require("http");

class VideoService {

constructor() {
this.items = ;
}

fetchVideos(token = "") {

const url = `https://www.example.com`;

http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}

});
}

getVideos() {
this.fetchVideos();

console.log(this.items.length); // this returns 0 instead of all items fetched

return this.items;
}

}

module.exports = VideoService;


In another file, I am using it like this:



const videoService = require("../shared/videoService");

const videos = (new videoService()).getVideos();
console.log(videos);


The last console.log call always returns empty array instead of all data collected in items property of the above class.



Can anybody tell what I am missing here?










share|improve this question


















  • 1





    Yeah so your function fetchVideos() has an http call which will be processed asynchronously. I suggest using something like a Promise or an Observable. You can read more about Promises here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – theapologist
    Nov 22 '18 at 13:52











  • To elaborate: the calls to .getJSON() return immediately, before the response to the underlying HTTP request has been received.

    – Pointy
    Nov 22 '18 at 13:53











  • @Pointy: Thanks but I am rather new to promises stuff I cannot understand how to modify this code to use promises. I will love to see fix in an answer so I can accept it. Thanks

    – dev0010
    Nov 22 '18 at 13:55











  • Your main issue is that you're not return a (resolved) Promise at the end of the recursion.

    – Alnitak
    Nov 22 '18 at 14:00











  • Maybe the following answer can help you out in making requests based on result of previous request.

    – HMR
    Nov 22 '18 at 14:02


















1















I have made a class which builds some data from api:



const http = require("http");

class VideoService {

constructor() {
this.items = ;
}

fetchVideos(token = "") {

const url = `https://www.example.com`;

http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}

});
}

getVideos() {
this.fetchVideos();

console.log(this.items.length); // this returns 0 instead of all items fetched

return this.items;
}

}

module.exports = VideoService;


In another file, I am using it like this:



const videoService = require("../shared/videoService");

const videos = (new videoService()).getVideos();
console.log(videos);


The last console.log call always returns empty array instead of all data collected in items property of the above class.



Can anybody tell what I am missing here?










share|improve this question


















  • 1





    Yeah so your function fetchVideos() has an http call which will be processed asynchronously. I suggest using something like a Promise or an Observable. You can read more about Promises here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – theapologist
    Nov 22 '18 at 13:52











  • To elaborate: the calls to .getJSON() return immediately, before the response to the underlying HTTP request has been received.

    – Pointy
    Nov 22 '18 at 13:53











  • @Pointy: Thanks but I am rather new to promises stuff I cannot understand how to modify this code to use promises. I will love to see fix in an answer so I can accept it. Thanks

    – dev0010
    Nov 22 '18 at 13:55











  • Your main issue is that you're not return a (resolved) Promise at the end of the recursion.

    – Alnitak
    Nov 22 '18 at 14:00











  • Maybe the following answer can help you out in making requests based on result of previous request.

    – HMR
    Nov 22 '18 at 14:02
















1












1








1








I have made a class which builds some data from api:



const http = require("http");

class VideoService {

constructor() {
this.items = ;
}

fetchVideos(token = "") {

const url = `https://www.example.com`;

http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}

});
}

getVideos() {
this.fetchVideos();

console.log(this.items.length); // this returns 0 instead of all items fetched

return this.items;
}

}

module.exports = VideoService;


In another file, I am using it like this:



const videoService = require("../shared/videoService");

const videos = (new videoService()).getVideos();
console.log(videos);


The last console.log call always returns empty array instead of all data collected in items property of the above class.



Can anybody tell what I am missing here?










share|improve this question














I have made a class which builds some data from api:



const http = require("http");

class VideoService {

constructor() {
this.items = ;
}

fetchVideos(token = "") {

const url = `https://www.example.com`;

http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}

});
}

getVideos() {
this.fetchVideos();

console.log(this.items.length); // this returns 0 instead of all items fetched

return this.items;
}

}

module.exports = VideoService;


In another file, I am using it like this:



const videoService = require("../shared/videoService");

const videos = (new videoService()).getVideos();
console.log(videos);


The last console.log call always returns empty array instead of all data collected in items property of the above class.



Can anybody tell what I am missing here?







javascript node.js ecmascript-6






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 22 '18 at 13:49









dev0010dev0010

184




184








  • 1





    Yeah so your function fetchVideos() has an http call which will be processed asynchronously. I suggest using something like a Promise or an Observable. You can read more about Promises here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – theapologist
    Nov 22 '18 at 13:52











  • To elaborate: the calls to .getJSON() return immediately, before the response to the underlying HTTP request has been received.

    – Pointy
    Nov 22 '18 at 13:53











  • @Pointy: Thanks but I am rather new to promises stuff I cannot understand how to modify this code to use promises. I will love to see fix in an answer so I can accept it. Thanks

    – dev0010
    Nov 22 '18 at 13:55











  • Your main issue is that you're not return a (resolved) Promise at the end of the recursion.

    – Alnitak
    Nov 22 '18 at 14:00











  • Maybe the following answer can help you out in making requests based on result of previous request.

    – HMR
    Nov 22 '18 at 14:02
















  • 1





    Yeah so your function fetchVideos() has an http call which will be processed asynchronously. I suggest using something like a Promise or an Observable. You can read more about Promises here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – theapologist
    Nov 22 '18 at 13:52











  • To elaborate: the calls to .getJSON() return immediately, before the response to the underlying HTTP request has been received.

    – Pointy
    Nov 22 '18 at 13:53











  • @Pointy: Thanks but I am rather new to promises stuff I cannot understand how to modify this code to use promises. I will love to see fix in an answer so I can accept it. Thanks

    – dev0010
    Nov 22 '18 at 13:55











  • Your main issue is that you're not return a (resolved) Promise at the end of the recursion.

    – Alnitak
    Nov 22 '18 at 14:00











  • Maybe the following answer can help you out in making requests based on result of previous request.

    – HMR
    Nov 22 '18 at 14:02










1




1





Yeah so your function fetchVideos() has an http call which will be processed asynchronously. I suggest using something like a Promise or an Observable. You can read more about Promises here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

– theapologist
Nov 22 '18 at 13:52





Yeah so your function fetchVideos() has an http call which will be processed asynchronously. I suggest using something like a Promise or an Observable. You can read more about Promises here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

– theapologist
Nov 22 '18 at 13:52













To elaborate: the calls to .getJSON() return immediately, before the response to the underlying HTTP request has been received.

– Pointy
Nov 22 '18 at 13:53





To elaborate: the calls to .getJSON() return immediately, before the response to the underlying HTTP request has been received.

– Pointy
Nov 22 '18 at 13:53













@Pointy: Thanks but I am rather new to promises stuff I cannot understand how to modify this code to use promises. I will love to see fix in an answer so I can accept it. Thanks

– dev0010
Nov 22 '18 at 13:55





@Pointy: Thanks but I am rather new to promises stuff I cannot understand how to modify this code to use promises. I will love to see fix in an answer so I can accept it. Thanks

– dev0010
Nov 22 '18 at 13:55













Your main issue is that you're not return a (resolved) Promise at the end of the recursion.

– Alnitak
Nov 22 '18 at 14:00





Your main issue is that you're not return a (resolved) Promise at the end of the recursion.

– Alnitak
Nov 22 '18 at 14:00













Maybe the following answer can help you out in making requests based on result of previous request.

– HMR
Nov 22 '18 at 14:02







Maybe the following answer can help you out in making requests based on result of previous request.

– HMR
Nov 22 '18 at 14:02














1 Answer
1






active

oldest

votes


















1














This happens because in your function fetchVideos(), you are making an http call which will be processed asynchronously. You can try to process it this way.



fetchVideos(token = "") {

const url = `https://www.example.com`;

return http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}
else return new Promise((resolve, reject)=>{
resolve();
});

});
}

getVideos() {
return this.fetchVideos().then(function(){
console.log(this.items.length); // this returns 0 instead of all items fetched
return this.items;
});
}


I suggest reading about promises and asynchronicity in javascript. Check this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise






share|improve this answer





















  • 1





    This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

    – Pointy
    Nov 22 '18 at 13:57











  • @Pointy nice catch. I did not notice that before.

    – theapologist
    Nov 22 '18 at 14:00











  • @LloydFrancis: It still does not work as expected, console.log does not show any results.

    – dev0010
    Nov 22 '18 at 14:05






  • 1





    The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

    – Alnitak
    Nov 22 '18 at 14:29






  • 1





    else return Promise.resolve()

    – Alnitak
    Nov 23 '18 at 13:50











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%2f53432441%2fjavascript-returning-array-from-recursive-function%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









1














This happens because in your function fetchVideos(), you are making an http call which will be processed asynchronously. You can try to process it this way.



fetchVideos(token = "") {

const url = `https://www.example.com`;

return http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}
else return new Promise((resolve, reject)=>{
resolve();
});

});
}

getVideos() {
return this.fetchVideos().then(function(){
console.log(this.items.length); // this returns 0 instead of all items fetched
return this.items;
});
}


I suggest reading about promises and asynchronicity in javascript. Check this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise






share|improve this answer





















  • 1





    This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

    – Pointy
    Nov 22 '18 at 13:57











  • @Pointy nice catch. I did not notice that before.

    – theapologist
    Nov 22 '18 at 14:00











  • @LloydFrancis: It still does not work as expected, console.log does not show any results.

    – dev0010
    Nov 22 '18 at 14:05






  • 1





    The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

    – Alnitak
    Nov 22 '18 at 14:29






  • 1





    else return Promise.resolve()

    – Alnitak
    Nov 23 '18 at 13:50
















1














This happens because in your function fetchVideos(), you are making an http call which will be processed asynchronously. You can try to process it this way.



fetchVideos(token = "") {

const url = `https://www.example.com`;

return http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}
else return new Promise((resolve, reject)=>{
resolve();
});

});
}

getVideos() {
return this.fetchVideos().then(function(){
console.log(this.items.length); // this returns 0 instead of all items fetched
return this.items;
});
}


I suggest reading about promises and asynchronicity in javascript. Check this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise






share|improve this answer





















  • 1





    This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

    – Pointy
    Nov 22 '18 at 13:57











  • @Pointy nice catch. I did not notice that before.

    – theapologist
    Nov 22 '18 at 14:00











  • @LloydFrancis: It still does not work as expected, console.log does not show any results.

    – dev0010
    Nov 22 '18 at 14:05






  • 1





    The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

    – Alnitak
    Nov 22 '18 at 14:29






  • 1





    else return Promise.resolve()

    – Alnitak
    Nov 23 '18 at 13:50














1












1








1







This happens because in your function fetchVideos(), you are making an http call which will be processed asynchronously. You can try to process it this way.



fetchVideos(token = "") {

const url = `https://www.example.com`;

return http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}
else return new Promise((resolve, reject)=>{
resolve();
});

});
}

getVideos() {
return this.fetchVideos().then(function(){
console.log(this.items.length); // this returns 0 instead of all items fetched
return this.items;
});
}


I suggest reading about promises and asynchronicity in javascript. Check this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise






share|improve this answer















This happens because in your function fetchVideos(), you are making an http call which will be processed asynchronously. You can try to process it this way.



fetchVideos(token = "") {

const url = `https://www.example.com`;

return http.getJSON(url).then((results) => {
results.items.forEach((item, index) => {
const vid = item.snippet.resourceId.videoId;

this.items.push({
title: item.title,
date: item.publishedAt
});

console.log(this.items.length); // here length inreases, works here
});

if (typeof results.nextPageToken !== "undefined") {
return this.fetchVideos(results.nextPageToken);
}
else return new Promise((resolve, reject)=>{
resolve();
});

});
}

getVideos() {
return this.fetchVideos().then(function(){
console.log(this.items.length); // this returns 0 instead of all items fetched
return this.items;
});
}


I suggest reading about promises and asynchronicity in javascript. Check this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 17:52

























answered Nov 22 '18 at 13:56









theapologisttheapologist

566215




566215








  • 1





    This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

    – Pointy
    Nov 22 '18 at 13:57











  • @Pointy nice catch. I did not notice that before.

    – theapologist
    Nov 22 '18 at 14:00











  • @LloydFrancis: It still does not work as expected, console.log does not show any results.

    – dev0010
    Nov 22 '18 at 14:05






  • 1





    The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

    – Alnitak
    Nov 22 '18 at 14:29






  • 1





    else return Promise.resolve()

    – Alnitak
    Nov 23 '18 at 13:50














  • 1





    This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

    – Pointy
    Nov 22 '18 at 13:57











  • @Pointy nice catch. I did not notice that before.

    – theapologist
    Nov 22 '18 at 14:00











  • @LloydFrancis: It still does not work as expected, console.log does not show any results.

    – dev0010
    Nov 22 '18 at 14:05






  • 1





    The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

    – Alnitak
    Nov 22 '18 at 14:29






  • 1





    else return Promise.resolve()

    – Alnitak
    Nov 23 '18 at 13:50








1




1





This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

– Pointy
Nov 22 '18 at 13:57





This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback in fetchVideos().

– Pointy
Nov 22 '18 at 13:57













@Pointy nice catch. I did not notice that before.

– theapologist
Nov 22 '18 at 14:00





@Pointy nice catch. I did not notice that before.

– theapologist
Nov 22 '18 at 14:00













@LloydFrancis: It still does not work as expected, console.log does not show any results.

– dev0010
Nov 22 '18 at 14:05





@LloydFrancis: It still does not work as expected, console.log does not show any results.

– dev0010
Nov 22 '18 at 14:05




1




1





The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

– Alnitak
Nov 22 '18 at 14:29





The fetchVideos function is failing to return a Promise at the end of the chain of recursive calls

– Alnitak
Nov 22 '18 at 14:29




1




1





else return Promise.resolve()

– Alnitak
Nov 23 '18 at 13:50





else return Promise.resolve()

– Alnitak
Nov 23 '18 at 13:50


















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%2f53432441%2fjavascript-returning-array-from-recursive-function%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

Create new schema in PostgreSQL using DBeaver

Deepest pit of an array with Javascript: test on Codility

Fotorealismo