Simple And Bug-Free Code With Dart Operators
Leveraging the full power of Dart operators and notations
This article is the first in a series of articles dedicated to understanding the Dart language better and using it more efficiently.
Dart(2.0+) and Flutter are both relatively new and an immense amount of people are joining the developer community each day. A lot of examples of code used by newer developers just use the same patterns as other languages and don’t use the full operator set that Dart offers.
In this article, we’ll be looking at operators that Dart offers to simplify code and make operations safer.
1. ?: (Ternary Operator)
The ternary operator already exists in most languages, but we’ll discuss it here for a more complete flow.
The ternary operator allows a more simplified flow if there are two possible paths without using if-else.
For example, instead of:
We can do:
The structure of the ternary operator goes like this:
condition ? (statement if true) : (statement if false);
If there is assignment involved, return
needs to be added at only the start and not the individual statements.
return condition ? (statement if true) : (statement if false);
and not
condition ? return (statement if true) : return (statement if false);
2. ??
??
is a null check operator. In this example, if person.name
is null, then name
is assigned a value of “John Doe”
. This simplifies code massively by reducing the need to check if name is null and then assigning something else instead.
This is much simpler than doing something like:
??
makes it much easier to handle unanticipated nulls turning up without having massive code to deal with it.
3. ?.
Imagine a class called Point
, which has x and y values.
class Point {
int x;
int y;
Point(this.x, this.y);
}
If we had an uninitialised Point
object and we tried to access the inner members, it wouldn’t give us null, it would throw an error instead.
For example:
Point point;
print(point.x);
Would throw:
Unhandled exception:
NoSuchMethodError: The getter 'x' was called on null.
Receiver: null
Tried calling: x
If instead, it just returned a null, we can easily handle and work around the problem of it being not initialised.
Again, the simplest solution would involve if-else.
This isn’t that bad to do, but it hits its limitations very quickly.
When we parse JSON for example, it has a lot of nested data which could easily be multiple layers deep.
As an example:
pages[0].contributors[0].authorDetails.basicInfo.firstName
In this call, every part has a possibility to be null if there are any kinds of errors. For example, authorDetails
may not have a basicInfo
field at all.
In these types of cases, null checks are a nightmare. Also, the entire call fails if even one field of these is null (except the firstName
, since it is the last one).
So what do we do for this? There’s no easy if-else or ternary solution. Also, in a perfect system, this error won’t exist at all, but we don’t always have perfect systems and APIs.
For this, the ?.
operator comes handy.
The operator roughly translates to “If the object is not null, access inner field, else return null.”
Hence, even our earlier point.x
example would throw a null instead of an error. This makes our job much easier and we can simply handle a null error by using our last operator.
Here, if point is uninitialised, instead of throwing an error, it returns a null. This null is then caught by our null check operator which assigns a value 0 to the variable x.
Similarly, we can fix our earlier example like:
pages[0]?.contributors[0]?.authorDetails?.basicInfo?.firstName ?? "N/A";
Now, if any part is null, it will return a value of “N/A”.
4. ??=
??=
simply means “If left hand side is null, carry out assignment”. This will only assign a value if the variable is null.
Unnecessary reassignments of values to variables can be avoided.
5. =>
=>
is known as the fat arrow notation in Dart.
It can be used in two different ways. Both have to do with defining functions.
The first way it can be used is as a shorthand for returning something.
So => x
simply means {return x;}
However, the operator also works for single statement even without returning anything.
Note that if the return type is void, even => s
will not return anything.
6. .. (Cascade notation)
The cascade notation is a simple way to change properties of an object, usually while creating it, rather than getting a reference to the object and changing properties one by one.
The first example we’ll take is our Point
class again.
Imagine a situation where we first need to initialise the class and then set the x and y properties. This is what you probably imagined:
Point p = Point();
p.x = 3;
p.y = 6;
The cascade notation gives us an easier way to do it without using the object again to set properties.
Note that if we had just used the .
operator, it would not return a Point
object on the first line.
What the cascade notation essentially does is:
- Create the
Point
object to default values - Change any affected values by the cascade operations
- Return the original object (Here, the instantiated
Point
object)
This is very useful for when a lot of properties need to be set, in the Builder pattern for example.
The best example for this comes out of the Dart documentation:
If you want to explore cascades further, this is a very good resource. Note that the article is VERY old, but it gets the explanation done.
7. ~/
Dart also has a few operators for speeding up arithmetic operations.
The ~/
operator divides and returns the floored (integer part) of the result.
These were a few operators which simplify and keep your code bug resistant. Now, to look ahead.
8. Bonus: (Planned, not released) Spread operator: …
(EDIT: The spread operator is now released and available to use)
There is talk of adding a …
operator to Dart as a spread operator for collections. Lists can be easily unpacked with this operator.
This will add elements of demoList
directly to the list instead of adding it as a List
object.
That’s it for this article! I hope you enjoyed it, and be sure to follow me for more Flutter articles and comment for any feedback you might have about this article.