questionmark

1.0.3 • Public • Published

questionmark.js

A tiny and mighty utility for optional chaining in pure JavaScript.

# get it  
npm install questionmark
const q = require('questionmark');
 
// If data.foo.bar.baz[0].bat[10] exists, its value will be returned.
// If any of bar, baz, baz[0], or bat[10] don't exist, we return undefined.
// You don't have to worry about accessing properties on null/undefined anymore!
data.q(q => q.foo.bar.baz[0].bat[10]);
 
// Not sure if `data` itself is null or undefined? No problem. 
// Use this alternative syntax:
q(data, q => q.foo.bar.baz[0].bat[10]);
 
// q works with function invocations as well:
data.q(q => q.doSomethingGreat().result);

It's similar to idx.macro but doesn't get babel involved.

Tests

Lovingly tested in mocha.

npm test

Contribute

Fork and PR please.

Background: What is optional chaining?

Imagine you are accessing a property from a deeply nested JSON object (perhaps from a server response?)

fetch("https://www.example.com/api/libraryDb")
    .then(res => res.json())
    .then(json => {        
        let book = json
            .libraries["UL London"].shelves["Science Fiction"]
            .authors["Herbert, Frank"].mostPopularBook.title;
        $("#book-of-the-month")
            .text("The book of the month is: " + book);
    });

But if json, or json.libraries, or json.libraries["UL London"], or any other value in that chain is null or undefined, your callback will throw an exception. You have to write some verbose guard clauses against that:

    let book = !!json && !!json.libraries
        && !!json.libraries["UL London"]
        && !!json.libraries["UL London"].shelves
        && !!json.libraries["UL London"].shelves["Science Fiction"]
        && !!json.libraries["UL London"].shelves["Science Fiction"].authors
        && !!json.libraries["UL London"].shelves["Science Fiction"].authors["Herbert, Frank"]
        && !!json.libraries["UL London"].shelves["Science Fiction"].authors["Herbert, Frank"].mostPopularBook
        && json.libraries["UL London"].shelves["Science Fiction"].authors["Herbert, Frank"].mostPopularBook.title
        || "unknown";

Eugh!

Some languages have optional chaining to indicate that you only want to access a property if it exists; if not, further drill-downs just give you a null value. This way you don't have to test every single step in the chain, and can just check whether you have a real value at the end.

This is also proposed for JavaScript:

    let book = json?.libraries?["UL London"]?
        .shelves?["Science Fiction"]?
        .authors?["Herbert, Frank"]?
        .mostPopularBook?.title || "unknown"

That's much better. questionmark.js aims to tide us over while we wait.

    let book = json.q(q => 
        q.libraries["UL London"].shelves["Science Fiction"]
        .authors["Herbert, Frank"].mostPopularBook.title) 
    || "unknown";

Package Sidebar

Install

npm i questionmark

Weekly Downloads

0

Version

1.0.3

License

ISC

Unpacked Size

13.1 kB

Total Files

4

Last publish

Collaborators

  • daniel.rothig