This new JavaScript operator is an absolute game changer

With the new safe assignment ?= operator you’ll stop writing code like this:

JavaScript
// ❌ Before: // ❌ Deep nesting of try-catch for different errors async function fetchData() { try { const response = await fetch('https://api.codingbeautydev.com/docs'); try { const data = await response.json(); return data; } catch (parseError) { console.error(parseError); } } catch (networkError) { console.error(networkError); } }

And start writing code like this:

JavaScript
// ✅ After: async function fetchData() { const [networkError, response] ?= await fetch('https://codingbeautydev.com'); if (networkError) return console.error(networkError); const [parseError, data] ?= await response.json(); if (parseError) return console.error(parseError); return data; }

We’ve completely eradicated the deep nesting. The code is far more readable and cleaner.

Instead of getting the error in the clunky catch block:

JavaScript
async function doStuff() { try { const data = await func('codingbeautydev.com'); } catch (error) { console.error(error); } }

Now we do everything in just one line.

Instead of failing loudly and proudly, ?= tells the error to shut up and let us decide what do with it.

JavaScript
// ✅ if there's error: `err` has value, `data` is null // ✅ no error: `err` is null, `data has value async function doStuff() { const [err, data] ?= await func('codingbeautydev.com'); }

We can tell it to get lost:

JavaScript
async function doStuff() { // 👇 it's as good as gone here const [, data] ?= await func('codingbeautydev.com'); // ... }

We can announce it to the world and keep things moving:

JavaScript
async function doStuff() { const [err, data] ?= await func('codingbeautydev.com'); if (err) { console.error(err); } // ... }

Or we can stop immediately:

JavaScript
// `err` is null if there's no error async function doStuff() { const [err, data] ?= await func('codingbeautydev.com'); if (err) return; }

Which makes it such a powerful tool for creating guard clauses:

JavaScript
// ✅ avoid nested try-catch // ✅ avoid nested ifs function processFile() { const filename = 'codingbeautydev.com.txt'; const [err, jsonStr] ?= fs.readFileSync(filename, 'utf-8'); if (readErr) { return; } const [jsonErr, json] ?= JSON.parse(jsonStr); if (jsonErr) { return; } const awards = json.awards.length; console.log(`🏅Total awards: ${awards}`); }

And here’s one of the very best things about this new operator.

There are several instances where we want a value that depends on whether or not there’s an exception.

Normally you’ll use a mutable var outside the scope for error-free access:

JavaScript
function writeTransactionsToFile(transactions) { // ❌ mutable var let writeStatus; try { fs.writeFileSync( 'codingbeautydev.com.txt', transactions ); writeStatus = 'success'; } catch (error) { writeStatus = 'error'; } // do something with writeStatus... }

But this can be frustrating, especially when you’re trying to have immutable code and the var was already const before the time came to add try-catch.

You’d have to wrap it try, then remove the const, then make a let declaration outside the try, then re-assign again in the catch

But now with ?=:

JavaScript
function writeTransactionsToFile(transactions) { const [err, data] ?= fs.writeFileSync( 'codingbeautydev.com.txt', transactions ) const writeStatus = err ? 'error' : 'success' // // do something with writeStatus... }

We maintain our immutability and the code is now much more intuitive. Once again we’ve eradicated all nesting.

How does it work?

The new ?= operator calls the Symbol.result method internally.

So when we do this:

JavaScript
const [err, result] ?= func('codingbeautydev.com');

This is what’s actually happening:

JavaScript
// it's an assignment now const [err, result] = func[Symbol.result]( 'codingbeautydev.com' );

So you know what this means right?

It means we can make this work with ANY object that implements Symbol.result:

JavaScript
function doStuff() { return { [Symbol.result]() { return [new Error("Nope"), null]; }, }; } const [error, result] ?= doStuff();

But of course you can throw as always:

JavaScript
function doStuff() { throw new Error('Nope'); } const [error, result] ?= doStuff();

And one cool thing it does: if result has its own Symbol.result method, then ?= drills down recursively:

JavaScript
function doStuff() { return { [Symbol.result](str) { console.log(str); return [ null, { [Symbol.result]() { return [new Error('WTH happened?'), null]; } } ]; } } } const [error, result] ?= doStuff('codingbeautydev.com');

You can also use the object directly instead of returning from a function:

JavaScript
const obj = { [Symbol.result]() { return [new Error('Nope'), null]; }, }; const [error, result] ?= obj;

Although, where would this make any sense in practice?

As we saw earlier, ?= is versatile enough to fit in seamlessly with both normal and awaited functions.

JavaScript
const [error, data] ?= fs.readFileSync('file.txt', 'utf8'); const [error, data] ?= await fs.readFile('file.txt', 'utf8');

using

?= also works with the using keyboard to automatically clean up resources after use.

❌ Before:

JavaScript
try { using resource = getResource(); } catch (err) { // ... }

✅ After:

JavaScript
using [err, resource] ?= getResource();

How to use it now

While we wait for ?= to become natively integrated into JavaScript, we can start it now with this polyfill:

But you can’t use it directly — you’ll need Symbol.result:

JavaScript
import 'polyfill.js'; const [error, data] = fs .readFileSync('codingbeautydev.com.txt', 'utf-8') [Symbol.result]();

Final thoughts

JavaScript error handling just got much more readable and intuitive with the new safe assignment operator (?=).

Use it to write cleaner and more predictable code.



11 Amazing New JavaScript Features in ES13

This guide will bring you up to speed with all the latest features added in ECMAScript 13. These powerful new features will modernize your JavaScript with shorter and more expressive code.

11 Amazing New JavaScript Features in ES13

Sign up and receive a free copy immediately.

Leave a Comment

Your email address will not be published. Required fields are marked *