Arguments Optional Help (Solved)

So i am really confused on what the Arguments Optional challenge means. I’m returning the sum of both numbers if they are both numbers? If the first number is not i’m returning a function that adds two to your input? The requirements to pass say nothing about returning a function, yet the instructions do.

If i try to run addTogether(2)([3]) to pass the test, i get:

TypeError: addTogether(...) is not a function

So what am i doing? Can i just get a clear explanation of what i am supposed to be doing? Why return a function too add two if i can just return 5.

function addTogether() {
  var args = [].slice.call(arguments);
  return typeof args[0] === "number"  && typeof args[1] === "number" ? args[0]+args[1] : undefined
}

addTogether(2, 3)

Why Isn’t this working? That code is what i have so far.

Can you link to the challenge please?

–> https://www.freecodecamp.org/challenges/arguments-optional

It doesn’t seem like you are returning a function. So trying to invoke a function:

([3])

from the return of:

addTogether(2) 

is not possible because the return of addTogether(2) is either the value of index 0 and 1 added/concatenated or undefined based on your ternary condition.

You are supposed to return a function in order to learn Closure which they provide a link to for further reading. The point is you might not have both inputs during the first call so you return another function that essentially waits for the second input and then can complete the desired result. It’s also handy if you need to add two to a bunch of different things, you now have a way to reuse that code for a bunch of different cases.

Update on my code:

function addTogether() {
  var args = [].slice.call(arguments);
  return typeof args[0] === "number"  && typeof args[1] === "number" ? args[0]+args[1] : args.length  < 2 && typeof args[0] === "number" ? function sum(){} : undefined
}

addTogether(2)(3)

So how do i access the 3? Its also returning undefined because it somehow failed some of these tests:

  1. return typeof args[0] === "number" && typeof args[1] === "number"
  2. args.length < 2 && typeof args[0] === "number"

If i console.log the 2nd test i get true, yet i don’t get returned a function Like i wanted to: function sum(){}

The code you wrote returns undefined if the argument length is less than 2. You have to pass args[1] to your sum function and then do something with it. When you leave the brackets empty the function simply returns undefined. So even though you are calling this sum function you don’t do anything. It’s still a regular function that you have to define a return for if you want it to return something. Maye you should try to break it down into if/else statements so you can visually see the control flow you’re writing.

What is the function supposed to do? How to i access the 3 to compare it and sum it if needed.

The directions say the returned function should take one argument (the number that wasn’t provided the first time) and add it to the number that was provided the first time. You will still have access to the first number from the surrounding lexical scope.

So I’d check to see if there are two numbers given right off the bat, if there are then sum them and return them.

If there is only one, return a function that takes one parameter and adds it to the number that you were previously given.

1 Like

Would i have to check which number is missing?So i’m just adding the missing number if their is only 1. How do i access that 3 still? Do i even need too?

I think you are over thinking this problem.

You already put all of the arguments that could have been given into an array called args.

As long as you are inside of your function you will have access to that array. With that said you will always know that the first number that was passed is args[0]. So you should return your sum function to take one argument (num): the one you don’t have yet, and return from that function args[0] + num. (Here num is the parameter from your function definition you can call it anything it’s just the variable to hold the second number that will eventually be passed in.).

Something along the lines of

return function sum(num) {
  return argv[0] + num
}

here is where i am at:

function addTogether() {
    for (let i of arguments) {
        if (typeof i !== "number") {
            return undefined
        }
    }
    if (arguments.length === 2) {
        return arguments[0] + arguments[1];
    } else {
        return function sum(num) {
            if (typeof sum !== "number") {
                return undefined
            } else {
            return arguments[0] + num;
            }
        };
    }
}

addTogether(2)(3)

The addTogether(2)(3) test if the only one i’m failing, im getting undefined. I check for undefined at 2 places. One is a simple check the parameter, one is to check the before i add two together in the function if one of them is not a number. Why is it undefined?

You check to see if typeof sum !== "number" but it seems it’s a function in the current scope. So I think your test is failing there.

If i do console.log(arguments) i get { 0: 2 }. The only way i know how to access that 3 is in the function you gave me. That is why i put it there. If i do console.log(num) i get the number 3, so why would it fail. It being ina function shouldn’t affect it.

Right but you’re checking the typeof sum instead of the typeof num in the function you wrote. It being a function absolutely affects it. When you use typeof on a function it doesn’t return ‘number’ which is when you tell it to return undefined. You are literally telling the computer if the type of sum is not a number (which we both know it’s not, it’s a function) then return undefined, and so it does.

I meant num the parameter, not sum :l . My thing is, now im having trouble accessing that 2.

console.log(arguments) returns { 0: 3 } and num = 3 too. Why is this happening?

–> repl; https://repl.it/@John_Nicole/op

Your scope changed. You should go and read the closure link until you really understand it. Essentially when you console.log(arguments) from inside the nested function the actual arguments are different. In the outer function, the argument was 2, in the nested function the argument is 3. If you want to access the 2 you need to set the arguments from the outer function to some arbitrary variable and access them through that variable in the nested function. You already had it set up perfectly in the outer function with the args variable.
I would go back to that instead of working with the arguments object directly.

1 Like

Thanks i just got it. The 2nd parameter that is separated is targeted for the 2nd function is what you are saying? I saw a youtube video on closure, my loose understanding is that, one thing i can do, it get something out of scope and use it. This was the video i saw --> https://www.youtube.com/watch?v=yiEeiMN2Khs

Basically, each function has an arguments variable. So using that variable will produce different results in different contexts. In the outer functions it 2, but in the nested function, it was 3. So when you added arguments[0] to num you weren’t realizing they were pointing to the same value. It’s not really a 2nd parameter in this context. addTogether(2) is really sum. So you’re really just calling sum(3). That’s why arguments[0] pointed to different values depending on where it was cause there were two functions (scopes) with one parameter each. So you assign arguments to an array which you called args and access the 2 from the first function that way since arguments[0] will now point to a new value in the given scope. That’s what closure is basically, although you could have seen it better if they had you save the return of the first function and then made you use the nested function outside of its declaration, but, it’s still technically closure nonetheless.

Thanks so much, I’m starting to understand it a little bit more now :slight_smile: .

My new code was;

function addTogether() {
    for (let i of arguments) {
        var oneNumber = i
        if (typeof i !== "number") {
            return undefined
        }
    }
    if (arguments.length === 2) {
        return arguments[0] + arguments[1];
    } 
    
    else {
        return function sum(num) {
            if (typeof num !== "number") {
                return undefined
            } else {
            return oneNumber + num;
            }
        };
    }
}

addTogether(2)(3)

I saved the first value, so when i went to the 2nd function i could use it.

2 Likes