Skip to content

Validity

Numbers

Various kinds of math operations can produce ‘NaN’ (Not a Number) or infinity. For example dividing by zero or something which is not a number.

const v1 = 10/0; // Infinity
const v2 = 10/'oops'; // NaN

It happens more often than one thinks, if you’re trying to do some math operation on a variable which you think ought to contain a number, but in fact has something else. Using Typescript or using type hinting can help a lot to catch these kinds of bugs.

If any other operation is applied to infinity or NaN, the value is always infinity or NaN. What can happen then is a ‘bad’ value quickly spreads through the execution ‘infecting’ other parts. This makes it hard to track down.

function sum(a, b) {
return a + b;
}
sum(10, 2); // 12
sum(10, 10/'hello'); // NaN

That’s why it’s necessary to do some ‘guarding’ and check the validity of values at key points.

You can use in-built Javascript functions to check for these kinds of numbers:

Number.isNaN(10/'oops'); // true
Number.isFinite(10/0); // false
function sum(a, b) {
if (typeof b !=== `number`) throw new TypeError(`Param 'b' is not type number. Got: ${typeof b}`);
if (Number.isNaN(b)) throw new TypeError(`Param 'b' is NaN`);
if (!Number.isFinite(b)) throw new TypeError(`Param 'b' is Infinite`);
return a + b;
}
sum(10, 2); // 12
sum(10, 10/'hello'); // Throws an error letting us know we gave it a dodgy input

As you can see, writing defensive functions can add a lot of clutter. For your own code you may not need to worry too much about it, since you’re the only one calling your own functions. But for libraries like ixfx it is useful to have checks on incoming values. In the above example, we aren’t even checking the parameter a, that’d add even more lines of code!

Since you don’t want to repeat yourself, you could use the same function ixfx uses internally: Guards.throwNumberTest to do the checking. It generates a useful error message and it can also enforce certain ranges of values.

import { Guards } from 'https://unpkg.com/ixfx/dist/util.js';
function sum(a, b) {
// Throw an error if a or b is not 0 or above and a legit number
Guards.throwNumberTest(a, `positive`, `a`);
Guards.throwNumberTest(b, `positive`, `b`);
return a + b;
}
sum(10, 2); // 12
sum(10, 10/`hello`); // Throws an error letting us know we gave it a dodgy input

Type checking

Check the type of a variable with typeof:

typeof "hello"; // "string"
typeof 0; // "number"
typeof {temp:20}; // "object"
const fn = () => {}
typeof fn; // "function"

In action, compare the result of typeof with the name of a type:

if (typeof v === `string`) {
// variable is a string
}

Does an object contain a field?

Check if an object has a field using in. In the example below, we print one message if the object has the field humidity, another one if it doesn’t.

const test = (v) => {
let msg = ``;
if (`humidity` in v) {
msg = `Temp: ${v.temp} humidity: ${v.humidity}`;
} else {
msg = `Temp: ${v.temp}`;
}
return msg;
}
test({ temp: 10, humidity: 0.8 });
test({ temp: 20 });

As a side point, a cleaner way to write this would be using a ternary:

const test = (v) => (`humidity` in v) ?
`Temp: ${v.temp} humidity: ${v.humidity}` :
`Temp: ${v.temp}`;
}
test({ temp: 10, humidity: 0.8 });
test({ temp: 20 });