Javascript return

Can someone please explain why the function doesn’t return countArray.push(endNum);
in the code below:

function rangeOfNumbers(startNum, endNum) {
  if (endNum < startNum) {
    return [];
  }
  else {
    var countArray = rangeOfNumbers(startNum, endNum - 1);
    return countArray.push(endNum);
  }
};

The console says : “TypeError: countArray.push is not a function”

hey there, I’m not the best with recursion but if I had to guess I would say you are failing to reach your base case. I can see that on the last call of your function you are expecting to return an array, so you would expect push to work. Also, think about whether push is the best function to use here, if you think about it you will end up nesting a bunch of arrays inside an array instead of joining them together.

Also I would reconsider what your base case is returning. Your base case should happen with the simplest possible input which in this case is two of the same number. What do you want to return if you have two of the same number?

1 Like

I have found the solution and it is like this :

function rangeOfNumbers(startNum, endNum) {
  if (endNum < startNum) {
    return [];
  }
  else {
    var countArray = rangeOfNumbers(startNum, endNum - 1);
    countArray.push(endNum);
    return countArray;
  }
};

but my Question was about the message of the console and why is the Error.

@bedward

the reason you get the error its not a function is because countArray.push(endNum); is an array, so you would just be returning the array with endNum pushed on the end so recursion will end.

1 Like

actually I just pasted that in the challenge and it passed, I’m not seeing any error. It’s not how I solved it myself but it seems to work fine for me. I tried it in the console and it worked fine with no errors.

1 Like

Found the answer:
countArray.push(endNum); will return the length of the array after push.
if you do “”“return countArray.push(2,3,4);”"" it will return 3 which is the length of resulting array after push method. If you do “”“return countArray”"" we are returning array not just length of array.
proof:

2 Likes

Why would it end:
countArray = rangeOfNumbers(startNum, endNum - 1)
which means it will return:
rangeOfNumbers(startNum, endNum - 1).push(endNum)
and the function will call itself again, can you explain more please?

@bedward
actually your right i wasnt thinking of the else statement

1 Like

So? any idea why the console shows error?

can you link me to the challenge?

Sure, https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/use-recursion-to-create-a-range-of-numbers

I got it…
I want you to figure out by yourself…
so take out your pen and paper, and assume some value for startNum and endNum, such as 2 and 5…
Manualy follow your own code and remember Array.push() method returns a number not an array…


If you still have problem with recognising the error, just let me know…

1 Like

@bedward yeah @boscojfelix was right i just didnt know why that was returning it like that cuz iv never tried to return a push before, but basically you have to push before you return the array and the goes for pop, shift and unshift too, more info here https://stackoverflow.com/questions/34259126/why-does-array-prototype-push-return-the-new-length-instead-of-something-more-us

tbh after reading this i still dont understand why it works like this lol javascript is such a confusing language and you learn something new everyday.

1 Like

Check this Video.

1 Like

lets take 2 as startNum and 5 as endNum:
/*we call the function–>*/rangeOfNumbers(2, 5);
endNum > startNum
countArray = rangeofnumbers(2, 4);
return rangeofnumbers(2,4).push(5) /***it will return countArray which is rangeOfNumbers of endNum - 1 ie :rangeofnumbers(2,4) ***/
and by repeating itself , the result would be like that
return [].push(2).push(3).push(4).push(5)
return [2,3,4,5]
that what i think, correct me if i am wrong

Thanks for dedicating your time and helping to explain, i really appreciate that, i did watch the video and became more confused :laughing: ,
Now can you check if i am already understanding things correctly:
-[].push(1,2,3) make the array look like that : [1,2,3]
-return [].push(1,2,3) make the array look like that : [1,2,3] plus returns the length of the array.
-The function works like that: For example: rangeOfNumbers(1, 3) ---> [].push(1).push(2).push(3) and after processing we have [1,2,3]

noooooo…
I think I found what’s the problem.

after running "return countArray.push(endNum)" in recursion mode you will have this:

first : “countArray” gets [ ] because you call next “rageOfNumbers” functions, where they are equaled to “countArray”.
then: it comes back to a higher level and with that if statement you set, push the new number to [ ] and now your array is [number] (not an empty array).
then: but because in the previous step you just return push method id didn’t return an array to use in a higher level of recursion and in next steps we just have a number that returns from push method which we can’t invoke push method on a number and we get an error.

is it clear?

1 Like

it errors out here, because the result of [].push(1) is not an array, but a number
if you have

let arr = []
arr.push(1).push(2)

it also errors out, but in this case the side effect of push can be seen, before it stops executing for the error, arr has become [1]

1 Like
[].push(1).push(2).push(3)

The above code will give following error:
image

Example [].push(1,2) will return 2 not [1,2]. 2 is the length of resulting array after push method.

2 Likes

Thank you all for your contributions and your time, very appreciated! <3