JavaScript: Returning array from recursive function
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
|
show 1 more comment
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
1
Yeah so your functionfetchVideos()
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
|
show 1 more comment
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
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
javascript node.js ecmascript-6
asked Nov 22 '18 at 13:49
dev0010dev0010
184
184
1
Yeah so your functionfetchVideos()
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
|
show 1 more comment
1
Yeah so your functionfetchVideos()
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
|
show 1 more comment
1 Answer
1
active
oldest
votes
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
1
This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback infetchVideos()
.
– 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
ThefetchVideos
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
|
show 1 more comment
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
1
This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback infetchVideos()
.
– 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
ThefetchVideos
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
|
show 1 more comment
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
1
This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback infetchVideos()
.
– 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
ThefetchVideos
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
|
show 1 more comment
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
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
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 infetchVideos()
.
– 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
ThefetchVideos
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
|
show 1 more comment
1
This is a good start, but things are much complicated by the fact that further HTTP requests are initiated in the callback infetchVideos()
.
– 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
ThefetchVideos
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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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