Non-Nullable Dart: Understanding Null Safety
- Getting Started
- Getting to Know the App
- Understanding Sound Null Safety
- Exploring the Dart Type System
- Enabling Null Safety
- Migrating to Null-Safe Dart
- Creating Model Classes
- Reviewing the Person Class
- Creating the User Class
- Creating Friend and FamilyMember Classes With Nullable Types
- Declaring Nullable Types
- Creating FamilyMember With a Nullable Property
- Using Late Variables and Lazy Initialization
- Retrieving Data From Widgets
- Understanding the Never Type
- Understanding Flow Analysis
- Testing the Never Type
- Using Type Promotion
- Displaying Member Names on the Home Screen
- Displaying User Details in the Dialog
- Retrieving User Input From the TextFields
- Displaying the Dialog With the User Information
- Displaying the User Relationship
- Clearing the UI
- Sound Null Safety In a Nutshell
- Where to Go From Here?
Null safety helps you solve one of the most common errors in software development: NullPointerException. This exception and other types of bugs cost millions of dollars for businesses and corporations. As a result, many companies recruit developers with good error-handling skills.
Null safety is not a new concept. Other languages such as Swift, Kotlin and Rust, have implemented null safety based on their type systems and language features. Dart has also recently introduced sound null safety.
In this tutorial, you’ll build ProfileApp, a small app that saves data about users and their relationships. In the process, you’ll learn about:
- Sound null safety.
- How to create a Flutter app with null-safe code.
- The type system in Dart.
- How to work with nullable types.
- What type promotion is and how Dart automatically promotes types.
- The migration types you can use to make your existing code null safe.
Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial. After the download completes, unzip the file to a suitable location.
ProfileApp consists of two screens and one dialog. In the first screen, the user enters their own data. In the second, they can add relatives or friends based on their preferences. Finally, users can review the entered data in the dialog widget. Follow the instructions in the next section to try the app out for yourself.
Getting to Know the App
Open the starter project in Android Studio by clicking Open an Existing Project in the Welcome to Android Studio window:
Browse to the location where you unzipped the file. Choose the starter folder and click Open:
The project structure should look like this:
The project already contains most of the UI code. You’ll concentrate on using model classes to save user-entered data and integrating that data into the existing UI components.
Inside Android Studio, open the terminal and enter flutter pub get to get all the packages:
Build and run the app. You’ll see the home page:
Tapping the + button opens the Add member page. You can add friends or family members here:
Go back to the previous screen. Tap the Save & Preview button and the User details dialog appears:
Right now, you can add people, but they don’t appear on the home page. Furthermore, the dialog is missing some information. You’ll fix these issues using null-safe code. Next, you’ll learn about what sound null safety is.
Understanding Sound Null Safety
Null is just the absence of a value for an object, which Dart needs to be able to represent.
null helps developers deal with the unknown in their code.
When any exception is not handled, the app will show a red error screen. If you try to call a method or getter on a null object, Dart will throw a
NoSuchMethodError. This is essentially the same as a
NullPointerException from other languages such as Java. For the purposes of this article, the term NullPointerException (NPE) will be used to discuss null errors since it is the more commonly used term.
The main issue with the NullPointerException is that it can happen at almost any part of the app if not well handled. Checking for nulls every now and then throughout your app isn’t the best either. For these reasons and more, handling nulls at the language level is probably the best way to avoid the dreaded NullPointerEception.
To build on this idea, the Dart team introduced sound null safety. This means that variables are considered non-nullable by default. If you don’t give an object null support when you create it, it will never get a
null. As a result, you avoid null reference errors in your code.
Before going into details about null safety and how it works, you have to understand the type system in Dart. The Dart team relied on the type system when they implemented null safety.
Exploring the Dart Type System
Dart divides types into two groups:
- Nullable types
- Non-Nullable types
Nullable types can contain either a value or null. There are certain types of operators that help you work with nullable types. The figure below is an example representing a nullable
Non-Nullable types can only contain values. Nulls are not permitted.
The type hierarchy of Dart is as follows:
Object? is at the top and
Never is at the bottom. You’ll rarely use
Never, though. Any code that returns or evaluates to
Never either throws an exception or aborts the program.
Now that you know what null safety is, you need to enable it before you can work with it.
Enabling Null Safety
Dart introduced a stable version of null safety in version 2.12.0. On the terminal, you can run flutter –version to verify your version is at least up to version 2.12.0. Alternatively, you can simply follow the steps below to download the latest release from the stable channel.
In the terminal, run the flutter channel command to check which channel you are currently using:
Run the flutter channel stable command to switch to the stable channel:
Update to the latest version by running the flutter upgrade command:
Open pubspec.yaml and confirm your SDK version under the
environment section looks like below:
sdk: ">=2.12.0 <3.0.0"
This changes the Dart version to 2.12.0.
Finally, run flutter upgrade again to avoid future problems with Android Studio:
Congratulations! You’ve just migrated your project to null safety. You can now use null safety in your project.
Migrating to Null-Safe Dart
Dart introduced null safety in 2.12.0, but there are old Dart codes in production. Since the Dart team can’t migrate your code automatically. You have two options:
- Migrate using a tool that makes easily predictable changes for you. Based on your needs, you can choose to apply those changes or not.
- Migrate manually, where you can easily predict most of the changes that need null safety and migrate accordingly. This involves manually refactoring your code.