
While watching the Angular Documentary, I came across a segment1 featuring Alex Rickabaugh, a core member of the Angular team. He discussed a subtle but impactful design choice from Angular’s early development: returning null in many places where JavaScript developers might expect undefined. What sounds like a minor quirk is actually a remnant of Angular’s close collaboration with Dart. That insight ignited my curiosity, prompting me to dive deeper into the framework’s history - and ultimately, it led me to research this topic further and write this article.
Dart’s Imprint on Angular
When Angular 2 was being built, it aimed to become a next-generation framework that could seamlessly target both TypeScript and Dart. At the time, Google had high hopes for Dart as a dominant web language, and Angular’s design had to be compatible with Dart’s constraints. One key detail? Dart doesn’t have undefined - only null 2.
This difference significantly influenced Angular’s internals. In JavaScript and TypeScript, undefined is a common way to say “there’s no value here,” but Dart had only null. To keep Angular uniform across both TypeScript and Dart, the team standardized on null. Consequently, in many internal APIs and public behaviors - like handling dependency injection, form controls, and asynchronous data - Angular returns null where pure JavaScript developers might have expected undefined.
Although Google’s push for Dart as a mainstream web language eventually waned, this early design choice became a permanent part of Angular’s DNA.
Two Ways to Say “No Value”: null vs. undefined
Why does JavaScript even have two different ways3 to represent nothing? It boils down to JavaScript’s rapid inception. During its creation, undefined emerged to represent an uninitialized variable, while null was intended for an intentionally empty or non-existent value 4. Over time, this duality caused confusion:
- Loose equality:
null == undefinedistrue, yetnull !== undefinedunder strict checking. - Frequent checks: Developers often feel compelled to write extra conditions (
if (value != null)), ensuring they don’t trip over a silent bug.
Tony Hoare once called null a “billion-dollar mistake” for the endless crashes and bugs it has caused 5. Yet, in Angular, null continues to dominate, mainly due to historical ties with Dart.
A Shift to TypeScript… But null Stays
When Angular 2 launched in 2016 6, Google had scaled back Dart’s role in mainstream web development, and TypeScript was rapidly rising. Angular pivoted to fully embrace TypeScript; however, the decision to use null was already woven into Angular’s infrastructure. Changing it after the fact would have been enormously disruptive, touching everything from forms to dependency injection to how observables emit initial values.
These are some notable areas where null appears in Angular instead of undefined:
- Dependency Injection: When a service is optional and not provided, Angular returns
null. - Forms: Empty or uninitialized form controls often begin with
null. - Async Values: The
asyncpipe emitsnullinitially, before any observable data arrives 7.
It’s not a bug - it’s simply a design choice. Yet it sometimes surprises modern developers who are used to undefined elsewhere in JavaScript/TypeScript.
Practical Implications
-
strictNullChecksgets noisy fast. Angular’s APIs returnnullwhere most TS code returnsundefined. With strict checks enabled, you’ll writeif (value !== null)far more than you’d expect - andif (value !== undefined)won’t save you. -
nullas intentional absence. There’s actually a useful semantic here:nullmeans “we looked and there’s nothing,” whileundefinedmeans “nobody set this yet.” Angular leans on that distinction. Whether your team does too is a different question - pick one convention and lint for it. -
Community has tried to fix this. Multiple GitHub issues 78 have proposed replacing
nullwithundefinedin Angular’s APIs. None have landed. The migration cost is enormous - every app that checks=== nullwould break. This is staying.
Looking Forward
Dart is gone from Angular’s story, but null isn’t going anywhere. The GitHub issues 78 proposing a switch to undefined are still open, still debated, and still unlikely to land - the migration surface is just too large. Angular’s null is the kind of decision that outlives the reason it was made. Understanding where it came from won’t change the API, but it’ll stop you from fighting it.