37

There's quite a few JavaScript idioms that coerce between types and similar things.

! can convert anything falsey to boolean true, !! can convert anything falsey to actual boolean false, + can convert true, false, or a string representing a number into an actual number, etc.

Is there something similar that converts undefined to null?

Now I'm using ternary ? : but it would be cool to know if I'm missing a useful trick.


OK, let me contrive an example ...

function callback(value) {
  return value ? format(value) : null;
}

callback is called by 3rd party code which sometimes passes undefined.
The 3rd party code can handle null being passed back, but not undefined. format() is also 3rd party and can't handle being passed either undefined or null.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
  • 2
    I'm not sure if there's a nice quick way to convert between them, but if it helps: `undefined == null` returns true, unlike `undefined === null` – Michael Horn Sep 08 '17 at 02:18
  • Can you provide an example of what you are trying to do? – Brr Switch Sep 08 '17 at 02:23
  • 3
    @VamshiGudipati: I was going to, but people would just tell me some other way to do that, so I decided not to. I just want to improve my vocabulary of JavaScript idioms and I think that's enough to make a good question. The whole point of idioms is that they have many uses. – hippietrail Sep 08 '17 at 02:25
  • Instead of converting them, you can use the truly or falsy value expression, `!!undefined // false` and `!!null // false` – Pedram marandi Sep 08 '17 at 02:37
  • @VamshiGudipati: I made up a contrived example anyway, just in case it helps. If it hinders I might remove it again (-: – hippietrail Sep 08 '17 at 03:04
  • "There's quite a few JavaScript idioms that coerce between types and similar things." --- those are not idioms. To convert something to a boolean idiomatically you use `Boolean()` function. – zerkms Sep 08 '17 at 03:20
  • 2
    I don't see how an operation to cast from `undefined` to `null` would be useful in your example. Are you trying to implement your `callback` as `return toNullIfUndefined(value) && format(value)`? I'd argue that your current code is clear, clean, and idiomatic. – Bergi Sep 08 '17 at 03:47
  • Or was the example wrong and you meant to have it `return format(value == undefined ? null : value)`? – Bergi Sep 08 '17 at 03:48
  • @Bergi: It could well be that for the contrived example that's as idiomatic as it gets. That's why I initially resisted making up an example (-: I should've included that `format()` can't handle being passed either `null` or `undefined`. – hippietrail Sep 08 '17 at 03:56
  • 1
    @hippietrail Well using `&&` instead of a ternary is rather unidiomatic, so this wouldn't have benefited from a `toNullIfUndefined` operator anyway. – Bergi Sep 08 '17 at 04:02
  • 2
    In case you're wondering why this is useful on some occasions - Angular form control object can be 'set' with an object, but if a property exists and is undefined you get an error 'Property X missing'. If that property had been 'null' you wouldn't have got the error. – Simon_Weaver Jan 25 '19 at 02:09

4 Answers4

30

Javascript now supports a null-coalescing operator: ??. It may not be production-ready (consult the support table), but it's certainly safe to use with Node or a transpiler (TypeScript, Babel, etc.).

Per MDN,

The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.

Much as || can provide a "default" value when the left operand is falsey, ?? provides a "default" value if the left operand is null or undefined. You can use this to coerce undefined to null:

    // OR operator can coerce 'defined' values
    "value"   || null;    // "value"
    0         || null;    // null
    false     || null;    // null
    ""        || null;    // null
    undefined || null;    // null
    
    // The null-coalescing operator will only coerce undefined or null
    "value"   ?? null;    // "value"
    0         ?? null;    // 0
    false     ?? null;    // false
    ""        ?? null;    // ""
    undefined ?? null;    // null

An example based on the question:

    function mustNotReturnUndefined(mightBeUndefined) { // can return null
        // Substitute empty string for null or undefined
        let result = processValue(mightBeUndefined ?? "");

        // Substitute null for undefined
        return result ?? null;
    }
snarf
  • 2,684
  • 1
  • 23
  • 26
24

undefined || null - or any falsey || null - will return null

Hugo Silva
  • 6,748
  • 3
  • 25
  • 42
  • 12
    What about the case where false and 0 are valid value that should not be converted? – Eric Mar 28 '18 at 00:41
  • 1
    what about it?? – Hugo Silva Mar 28 '18 at 00:58
  • 2
    What I mean is that it looks like your answer will fail when compared to these 2. Do you have an option which does a strict type check and only covers the undefined? I was looking for something that didn't use a for loop because I am looking to use it in a lot of methods to normalize the inputs – Eric Mar 29 '18 at 11:03
  • 4
    In that case you can use a ternary expression, similar to the example presented in the question: `value === undefined ? null : value` – Hugo Silva Apr 08 '18 at 21:15
2

This is a fairly old question and probably my answer is a little late, but I decided for myself in the following way:

const valueOrNull = (value = null) => value;

const a = { d: '' };
valueOrNull(a.b?.c) === null; // true
valueOrNull(a.d) === '';      // true
valueOrNull() === null;       // true

Any undefined value will get null as the default value;

Odeus
  • 93
  • 1
  • 6
-1
public static replaceUndefinedWithNull(object: any) {
 if (isUndefined(object)) {
  return null;
 }
return object;
}