0

I've been staring at this code for so long trying to understand what it's doing, but have no idea what's going on.

export const fieldDisabledIs = expectedValue => ({fieldDisabled}) =>
  (expectedValue === false && isEmpty(fieldDisabled)) || fieldDisabled === expectedValue;

The caller makes a call like this:

fieldDisabledIs(true)

What is it doing? I think since there are two arrow functions, the return is a function itself. Something like:

  function(expectedValue)
  {
    return function ({fieldDisabled})
    {
      (expectedValue === false && isEmpty(fieldDisabled)) || fieldDisabled === expectedValue;
    }
  }

Also this line here...

(expectedValue === false && isEmpty(fieldDisabled)) || fieldDisabled === expectedValue;

It seems redundant to have the first check if we can just compare fieldDisabled === expectedValue. Isn't it covered in the second condition?

  • 1
    The first check is necessary, because it's a separate condition that is being tested for. The first condition tests whether `(expectedValue === false && isEmpty(fieldDisabled))` and the second tests whether `fieldDisabled === expectedValue`. Since it's possible for either of those two conditions to be true, it's necessary to test them both. – kmoser Jul 27 '21 at 00:37
  • This is called currying. The internet can explain it better than me https://wiki.haskell.org/Currying#:~:text=Currying%20is%20the%20process%20of,the%20rest%20of%20that%20tuple. – Jazz Jul 27 '21 at 00:43
  • @kmoser could you expand on that. Why is it a separate condition was my question. Wouldn't checking if both are equal good enough – Johnny Manzel Jul 27 '21 at 00:48
  • @JohnnyManzel Because in the event that the second condition is false (e.g. when `fieldDisabled = ''` and `expectedValue = false`), the first condition will be true. – kmoser Jul 27 '21 at 01:56
  • @James it really is..... - there are two values, expected value and {fieldDisabled}. Why would this not be currying? – Jazz Jul 27 '21 at 09:18
  • @Jazz I had originally posted it was too, then removed it (you can see my comment is edited), but in reflection I agree not sure why I removed it and decided it wasn't now tbh – James Jul 27 '21 at 16:04

1 Answers1

0

The two arrow functions in the first line of the code is a technique called currying.

To quote wikipedia "In mathematics and computer science, currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each takes a single argument."

Well okay.. that's pretty obvious, but why would you do that.

In the case of your example this might be used as below.

You could create a 'checker' for a specifc value, in this example we will use 'foo'.

const fieldDisabledIsFoo = fieldDisabledIs('foo');

Then you could use your checker whenever you want to check if the disabledField prop equals 'foo', without having to pass 'foo' again.

const myTestObj = { fieldDisabled: 'foo' };
fieldDisabledIsFoo(myTestObject) // === true;

And then you might define checkers for your expected values giving you a single checker function for each separate expected value and you dont have to pass these expected values in each time, or create a whole bunch of identical code. Pretty cool hey?

const fieldDisabledIsFalse = fieldDisabledIs(false);
const fieldDisabledIsBar = fieldDisabledIs('bar');
const fieldDisabledIsHello = fieldDisabledIs('hello');

To your second question. It seems as if they are not doing the same check.

I cant see what the isEmpty function does but I imagine it is something like

(str) => str.isEmpty()

If this is the case then the false checker will return true if the string is empty

const fieldDisabledIsFalse = fieldDisabledIs(false);
const myTestObj = { fieldDisabled: '' };
fieldDisabledIsFalse(myTestObject) // === true;

If the function did not have both checks the above check would return false, as an empty string '' does not strictly equal false.

Jazz
  • 341
  • 1
  • 6