Creative Bracket

Learn Dart before you Flutter

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 experiences like reactive programming and widget composition, using the Dart platform as its main base of operations.

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.

First Steps

Here is an example of a Dart program:

class Order {
  var _id;
  var _reference;
  var _date;
 
  Order(id, reference, date) {
    this._id = id;
    this._reference = reference;
    this._date = date;
  }
  
  getInfo() {
    return 'Your order information:' +
          '\n-------------------------------' +
          '\n  Id: $_id' +
          '\n  Reference: $_reference' +
          '\n  Date: $_date' +
          '\n-------------------------------';
  }
}

void main() {
  var order1 = new Order(1, 'ref1', new DateTime.now());
  print(order1.getInfo());
  // Expected output
  // Your order information:
  // -------------------------------
  //   Id: 1
  //   Reference: ref1
  //   Date: 2018-04-21 19:06:20.507
  // -------------------------------
}

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:

class Order {
  var _id;
  var _reference;
  var _date;
 
  Order(this._id, this._reference, this._date);
  
  getInfo() {
    return 'Your order information:'
          '\n-------------------------------'
          '\n  Id: $_id'
          '\n  Reference: $_reference'
          '\n  Date: $_date'
          '\n-------------------------------';
  }
}

void main() {
  var order1 = new Order(1, 'ref1', new DateTime.now());
  print(order1.getInfo());
}

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 getIntro 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 needs to be public:

Order(this._id, this._reference, [this.date]); // optional 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:

class Order {
  int _id;
  String _reference;
  DateTime _date;
  String code; // public property
 
  Order(this._id, this._reference, this._date);
  Order.withDiscount(this._id, this._reference, {this.code}) {
    _date = new DateTime.now();
  }
  
  // Shorthand methods FTW!!!
  String getInfo() => 'Your order information:'
    '\n-------------------------------'
    '\n  Id: $_id'
    '\n  Reference: $_reference'
    '\n  Date: $_date'
    '\n-------------------------------';
  
  void printInfo() => print(getInfo());
}

void main() {
  Order order1 = new Order.withDiscount(1, 'ref1', code: 'LOVETHEWEEKEND');
  order1.printInfo();
}

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 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:

class Order {
  // private properties
  int _id;
  String _reference;
  DateTime _date;
  
  // public properties
  String code;
  String from;
  List<String> bookings;
 
  Order(this._id, this._reference, this._date);
  Order.withDiscount(this._id, this._reference, {this.code}) {
    _date = new DateTime.now();
  }
  
  // Using doc strings to save the multiple linebreaks(\n)
  String getInfo() => '''
Your order information:
-------------------------------
  Id: $_id
  Reference: $_reference
  Date: $_date
-------------------------------
''';
  
  void printInfo() => print(getInfo());
}

void main() {
  Order order1 = new Order.withDiscount(1, 'ref1', code: 'SPECIALDISCOUNT')
    ..from = 'Jermaine Oppong'
    ..bookings = ['booking1', 'booking2', 'booking3']
    ..printInfo();
}

Conclusion

Thanks for reading through to the end. 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


Sharing is caring 🤗

If you enjoyed reading this post, please share this through the various social buttons hovering on the left/top side of the screen ↖️⬆️. Also, check out and subscribe to my YouTube channel (hit the bell icon too) for videos on Dart.

Watch my Free Get started with Dart course on Egghead.io and Subscribe to my email newsletter to download my Free 35-page eBook titled Get started with Dart and to be notified when new content is released.

Like, share and follow me 😍 for more content on Dart.

Jermaine Oppong

Hello 👋, I show programmers how to build full-stack web applications with the Dart SDK. I am passionate about teaching others, having received tremendous support on sites like dev.to and medium.com for my articles covering various aspects of the Dart language and ecosystem.