question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Erase null off the face of the Earth

See original GitHub issue

šŸš€ feature request

Relevant Package

This feature request is for @angular/core and @angular/forms, and maybe more.

Description

  • What is widely regarded as a big mistake in programming languages? null is.
  • What’s worse? Two forms of null with different types and different behavior (null and undefined).
  • What’s bad for optimization? Type coercion.

null/nil/nullptr/etc. have already caused plenty of harm across many programming languages. The fact that JavaScript has both null and undefined just makes things much much worse for developers.

I understand both Angular devs and many Angular users are coming from Java and lots of people want an extremely semantic type system which distinguishes between cases like ā€œit was never given a valueā€ (undefined) and ā€œit was explicitly given no valueā€ (null). I have written many, many thousands of lines of TypeScript code over my 4 years as an Angular developer and I must say that the distinction between the two is rarely important. A hallmark of good code is simplicity (good for the reader and good for the computer), and one way to obtain simple code is to write it for the common case and only get verbose for the rare cases. The only—and I mean only—time I have ever needed to use null in JavaScript/TypeScript was with a CRUD API where the PATCH body could contain a null expiration to clear the expiration date for an item (JSON does not have undefined and so undefined values get omitted by default when encoding). Additionally, if I were the API designer, I would have simply offered a query parameter in the URL to clear the expiration.

My point is that 99% of the time, null and undefined are used interchangeably and the end user sees the same thing regardless of which one made its way through the code. You can be type-religious all you want but I think most of us can agree that making rare distinctions with more verbose code beats using ā€˜nullish’ coercions all over the place (and crashing when you forget to).

That still leaves the question: which is the winner, null or undefined? There is an excellent article comparing them which you should definitely go read, but, in short, undefined is better supported by the language.

  • undefined is the initial value for unassigned variables, just as null is in Java.
  • The above also applies to object properties, and even if you need to distinguish between implicit/explicit absence of a value, you can use the in operator or the hasOwnProperty method (doesn’t check inherited properties).
  • null does not work with parameter defaults or destructuring defaults.
  • Saner typeof check: typeof undefined yields "undefined" whereas typeof null yields "object" but it still does not behave as a regular object at all.

I only use undefined in my code and it works out very well since, as I explained, it has lots of language support. I almost never need null checks (only for old APIs like local storage), but opting to use null religiously does not get anyone out of undefined checks.

Unfortunately, it seems like the Angular team disagrees, and now I have to write lots of special checks for FormControl values (Angular reactive forms), as well as for optional injection (the NullInjector).

class MyModalComponent {
    constructor(
        @Inject(MAT_DIALOG_DATA)
        @Optional()
        private readonly data: {
            readonly project?: ProjectInfo;
            readonly parentID?: string;
        } | null
    ) {
        // Could've just been a parameter default :/
        if (data === null) {
            this.data = data = {};
        }
    }
}

Because the application I work on has a lot of data types, it also has a lot of forms. I have been porting the application from AngularJS to Angular for months now, and both Angular material and reactive forms have been a big letdown. I do not mean to be rude—lots of the new Angular features are fantastic and the performance difference with AOT compilation is massive—but writing forms has proven incredibly tedious and frustrating, mostly due to bad APIs (like the new version of ng-messages). Having to coerce null to undefined everywhere when making API requests is just the cherry on top.

Describe the solution you’d like

Well, breaking existing project compatibility is bad. Then again, backwards-compatibility as the number one priority is also responsible for all of JavaScript and C++'s historical baggage. Rust bit the bullet and dropped green threads and garbage collection halfway through and became truly innovative as a result (a modern replacement for C/C++).

That said, changing the behavior of optional injection is probably not the move. šŸ˜… Maybe provide an @Opt() decorator which yields undefined if the injection token is not found and deprecate @Optional()?

Forms have proven much more of a nuisance than the optional injection null checks, and reactive forms’ usage of null is just the tip of the iceberg there.

I suppose I’m mostly just trying to start a conversation with the hopes that a future forms API benefits from it. I will also do my part and open source any reactive forms replacement I end up writing (which I certainly will!).

Describe alternatives you’ve considered

Writing lots of ā€˜nullish’ coercion code.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:7
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
jelbourncommented, Nov 5, 2020

I, and other folks on the team, definitely agree that the codebase should be much more consistent with null and undefined. The reality, though, is that it would be a really large undertaking to go do a comprehensive cleanup of this for the entire framework. Instead, we would want to focus on specific area, e.g. #25395 for the typing of @Optional and #13721 for forms. We’ll realistically be able to prioritize those kinds of issues sooner than a comprehensive code cleanup like this issue suggests. In that vein, I’m going to close this issue since it wouldn’t be practically actionable and suggest opening more specific issues for different parts of the codebase that aren’t already tracked.

I’m also going to try to incorporate guidance on null vs. undefined into our coding standards; I’ve added an item to our next team meeting to discuss this.

2reactions
samclauscommented, Nov 4, 2020

I’m also going to try to incorporate guidance on null vs. undefined into our coding standards; I’ve added an item to our next team meeting to discuss this.

Awesome! That’s all I could’ve hoped for.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Wipe off the face of the earth - Idioms by The Free Dictionary
To totally eliminate, eradicate, or destroy someone or something. The president vowed to wipe these terrorist scumbags off the face of the earth....
Read more >
What is another word for "wipe from the face of the earth"?
What is another word for wipe from the face of the earth? ; excise Ā· remove ; annihilate Ā· cream ; decimate Ā·...
Read more >
Definition of 'off/from the face of the earth' - Collins Dictionary
If you say that something will be wiped off the face of the earth or disappear from the face of the earth, you...
Read more >
How do I remove null data (gray lines) from view? - GitBook
In this case, we use gray, or 'null' to show that there is no data. To remove null data use the 'Remove samples...
Read more >
Google Earth Engine: remove masked/null value from a list
I am unsure why you need to filter null items in the list. There is no 'item' property in your image collection, so...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found