Given the ‘gold rush’ of technological innovations targeting the mobile space, developing mobile apps have never been easier, thanks to cross-platform solutions like Flutter, React Native, NativeScript, PhoneGap and so on.

Flutter in particular, has managed to successfully grab the attention of the development community by allowing an expressive style that makes it a joy building UIs for mobile apps. It incorporates certain concepts familiar to modern development experience like reactive programming and widget composition, using the Dart platform as its main base of operations.

Prefer a video?

So, what’s Dart?

Dart is an object-oriented programming language by Google, which aims to help the developer build modern web applications. It covers client, server and now mobile with Flutter. It comes with a range of tools including a virtual machine, core libraries and package management repository, lending enough ammunition to get started with on your next project.

Although Flutter is gaining traction, it can easily obscure the beauty of the Dart platform and what it offers, independently of Flutter.

In this article we will look at how we can write a Dart program, exploring some of its language features. This will hopefully gear you up with an overview to help you see Dart shining through as you develop your next app.

→ Continue reading on my blog

First Steps

Here is an example of a Dart program:

This demonstrates the blueprint for an Order with properties and methods. The main() top-level function is where you would bootstrap your Dart application.

Here, I’m hoping that you’ll begin to see how the syntax looks pretty familiar with other OO languages and you’ll feel right at home if you’ve programmed in Java, C# or even JavaScript(ES2015 and above).

That being said, Dart comes with some language features that will surely make you more productive as a developer. See this tweak to our earlier class:

Not much done here, however we now have a shorthand constructor that saves the repetition of reassigning the parameters passed into the class properties.

We’re also using adjacent strings by removing the plus(+) symbols from our getInfo method. Oh, and prefixing class properties with underscore (_) makes them private. It’s conventional and saves the need for typing the private keyword.

Ok, so let’s see how far we could go with this. Our constructor parameters are defined in a positional manner. This means that they are required. Dart allows us to define parameters that are optional, with two flavours: optional positional and optional named. These essentially allow us to have better flexibility in the way we define and use them:

Order(this._id, this._reference, [date]); // optional positional

Order(this._id, this._reference, {date}); // optional named

And their usage:

new Order(1, 'ref1', new DateTime.now()); // optional positional

new Order(2, 'ref2', date: new DateTime.now()); // optional named

And surely we can map this onto our internal property, although for optional named parameters the property has to be public:

Order(this._id, this._reference, [this.date]); // opt. positional

Order(this._id, this._reference, {this.date}); // optional named

I hope this seems predictable so far. Let’s now enforce some type information on our properties:

int _id;

String _reference;

DateTime _date;

Another common feature that OO languages have is the ability to declare a constructor multiple times, differentiated by the amount of parameters you pass into it. Dart instead gives you named constructors, which essentially allows you to add a namespace to your constructor, saving you from worrying about the parameter count:

Order(this._id, this._reference, [this.date]); // normal

Order.withDiscount(this._id, this._reference, this.code); // named

And we’ll instantiate that like so: new Order.withDiscount(...) . Let’s see our refactoring so far:

One last feature I would like to cover are method cascades. These allow you to use the chaining pattern for your getters and setters, made popular by JavaScript libraries namely jQuery. To demonstrate this, we’ll add another public property named bookings :

int _id;

String _reference;

DateTime _date;

String code;

List<String> bookings;

and when we instantiate our object we’ll do:

Order order1 = new Order.withDiscount(1, 'ref1', 'WEEKENDFTW1')

..code = 'WEEKENDFTW1'

..bookings = ['booking1', 'booking2', 'booking3'];

The double period(..) shows the cascades in action which always returns the instance each time. The chaining works with setters and also when you invoke methods.

Here’s a complete solution:

Conclusion

Learning these Dart concepts will take you far once you start building your Flutter applications, so it doesn’t come to you as a surprise.

To start off, why not try modifying the printed output to include the other order information? The complete example is readily accessible through the online Dart editor.

Further reading