addTogether Intermediate Scripting

One of the test doesn’t work. In fact it breaks the function before it evens starts. Is this a typo in challenge?

addTogether(5)(7) should return 12.

I get error:

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

No, this is not a typo or a mistake. If only one argument is provided and the argument is a number, then the function must return a function.

2 Likes

When we have a function with 4 parentheses (ie: function()()) java script expects a returned statement or else it will throw an error?

1 Like

You aren’t understanding the syntax here.

const thisReturnedAFunction = addTogether(5);
thisReturnedAFunction(7); // Should be 12

I understand that this is a requirement but I don’t understand

THIS: “function()()”

I tried looking for some documentation on the subject but to no avail so far.

Why does this “function()()” mean must return statement? I think logically it has to mean that, how else does it make the error disappear? And more importantly. Why…

Ok found this…

I have no idea what this sentence means, I’m sorry.


I still don’t think you are understanding what I am saying.

Create a function that sums two arguments together. If only one argument is provided, then return a function that expects one argument and returns the sum.

If you have two valid arguments, then your function returns A NUMBER.

If you only have one argument and it is a number, then your function returns A FUNCTION.

The function call addTogether(5) has one argument and it is a number, so the function addTogether() returned A FUNCTION. You can call A FUNCTION by using a pair of parenthesis and the arguments: (7)

So, addTogether(5)(7) calls the function addTogether(), gets back A FUNCTION, and then immediately calls this function with the argument 7.

What I was trying to ask… poorly mind you :):

What’s the difference between:

addTogether()()

vs

addTogether()

The first is calling 2 functions.

This is what I’ve got so far:

function addTogether() {
  let arg1 = typeof arguments[0];
  let arg2 = typeof arguments[1];

  if (arg2 === 'undefined') {
    let secondFunction = (first, second) => {
      return first + second;
    };

    return secondFunction(arg1);
  }

  if (arg1 == 'number' && arg2 == 'number') {
    console.log(arguments[0] + arguments[1]);
    return arguments[0] + arguments[1];
  }

  return undefined;
}

addTogether(5)(7);

And I keep getting this error:

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

This is not a function. This is a function call. secondFunction is your function (but it should only require one argument and it must also do input validation).

1 Like

Ok so I haven’t setup the validation yet but there’s progress. Thanks!

function addTogether() {
  let arg1 = typeof arguments[0];
  let arg2 = typeof arguments[1];

  if (arg2 === 'undefined') {
    return (secondFunction = (arg1) => {
      console.log(arg1, arguments[1], arguments[0]);
      return arg1 + arguments[0];
    });
  }

  if (arg1 == 'number' && arg2 == 'number') {
    console.log(arguments[0] + arguments[1]);
    return arguments[0] + arguments[1];
  }

  return undefined;
}

Something I’ve learned here is that if you return a function(not call a function), argument(s) you pass are not part of the arguments object in the second/following function and the fact they can be passed this way.

The console.log in the returned function demonstrate that.

if (arg2 === 'undefined') {
    return (secondFunction = (arg1) => {
      console.log(arg1, arguments[1], arguments[0]);
      return arg1 + arguments[0];
    });
  }

When we have a function like this:

function()() does it mean it expects a returned function or it will always fail?

So what’s happening here is something cool called “closure”.

function makeAdder(base) {
  return (number) => base + number;
}

const addFive = makeAdder(5);
console.log(addFive(6)); // Should be 11

When you create a function, it is aware of all of the variables it needs to work. In the example above, the returned function addFive() kept track of the base argument.

You can do some weird stuff with this

function makeCounter() {
  let count = 0;
  return () => count += 1;
}

const myCounter = makeCounter();
console.log("The count is: " + myCounter());
console.log("The count is: " + myCounter());
console.log("The count is: " + myCounter());
console.log("The count is: " + myCounter());
console.log("The count is: " + myCounter());

In this case, if you call addTogether with only one argument, then yes, the tests fail if you do not return a function.

I am not finished with the validation in the returned function but it should pass test for function(5)(7).

Locally I get 12

but it doesn’t pass the FCC test.

function addTogether() {
  let arg1 = typeof arguments[0];
  let arg2 = typeof arguments[1];

  if (arg2 === 'undefined') {
    return (secondFunction = (arg1) => {
      let arg0 = typeof arguments[0];
      console.log(arg0);
      if (arg0 === 'undefined') {
        return undefined;
      }
      console.log(arg1 + arguments[0]);
      return arg1 + arguments[0];
    });
  }
  if (arg1 === 'undefined') {
    return undefined;
  }
  console.log(arguments[0] + arguments[1]);

  return arguments[0] + arguments[1];
}

This is a baffling choice of name that’s making your code harder to read. You aren’t getting the actual argument here, you’re getting the type of the argument.


When you combine that confusing name with this line… I don’t see how you could possibly get the correct value returned from this function.

Does the test check for something else other than the output?

Getting the typeOf this argument is exacly what I want it to do. Yes I can refactor this entire algorithm as to make it “make it” clean code but it doesn’t explain why the test doesn’t pass when the output is 12.

No… But there is no possible way for that code to return the correct output.

Ok, if you test in the fCC console:

console.log(addTogether(5)(7)); 

You get

ReferenceError: assignment to undeclared variable secondFunction

If you fix that undefined variable problem, then it sort of works, but that’s because of some bizarre loophole that returns absolutely shocking behavior.

So… going back to what I said:

I would really fix this. It’s tying your logic in knots.

It even passes my automated test on my side. lol

See above. Your test environment is letting you be very sloppy and you have somehow found a bizarre mistake in JavaScript’s handling of closures.

const addTogether = require('../addTogether');
const chai = require('chai');
const expect = chai.expect;

describe('addTogether Test suite', () => {
  it('addTogether(2,3) shoud return 5', () => {
    const result = addTogether(2, 3);
    expect(result).to.be.eql(5);
  });

  it('addTogether(23, 30) should return 53', () => {
    const result = addTogether(23, 30);
    expect(result).to.be.eql(53);
  });

  it('addTogether(5)(7) should return 12', () => {
    const result = addTogether(5)(7);
    expect(result).to.be.eql(12);
  });

  it('addTogether() should return undefined', () => {
    const result = addTogether('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
    expect(result).to.be.eql(undefined);
  });

  it('addTogether(2, "3") should return undefined', () => {
    const result = addTogether(2, '3');
    expect(result).to.be.eql(undefined);
  });

  it('addTogether(2)([3]) should return undefined', () => {
    const result = addTogether(2, [3]);
    expect(result).to.be.eql(undefined);
  });
});

Your code is wrong.

You do not have strict mode enabled, and therefore your environment is letting you get away with this.

Even without this… again… your variable naming is a problem. Somehow there is as strange interaction between the closure and your variable shadowing. Your code does not do what you think it does.

1 Like