DEV Community

Elijah L.
Elijah L.

Posted on • Updated on

Effective Dart Tricks

No intro here, let's jump into some effective Dart language tricks and features.

Trick 1: Use the linter!

You're probably using VS Code or Android studio for development in Dart or Flutter projects. Anytime you see the red, blue, grey, or squiggles underneath your "bad" code - that's the linter at work.

All Dart and Flutter linter rules can be found here. See if any of these tickle your fancy.

To add one of these rules to your project, follow these steps:

  1. Create a new analysis_options.yaml file at the root off your project. This will be in the same directory as your pubspec.yaml file.

  2. Add the following snippet to tell your editor's analysis server there are some rules you'll be adding:

linter:
  rules:
Enter fullscreen mode Exit fullscreen mode
  1. Select a rule from the list and add it to your analysis_options.yaml
linter:
  rules:
    - lines_longer_than_80_chars
    - another_rule # add any rule from that list here
Enter fullscreen mode Exit fullscreen mode

Trick 2: Prevent classes from being inherited and instantiated

Typically, an abstract class would be used to create a non-instantiatable class. But occassionally you'll have a class you don't want inherited as well.

The Flutter SDK usees this trick internally with Curves and other classes.

class SomeClass {
  SomeClass._(); // Use a private, unnamed constructor.

  /// All members should now be static.
  static const name = 'SomeClass';

  /// Methods should be pure and static as well.
  static String someFunction(String person) => 'Hello, $person!';
}
Enter fullscreen mode Exit fullscreen mode

Use a private, unnamed constructor. To use any member with this class, you should use the key word static. Since static objects are class-level (not instance-level). It operates similarly to an enum object when accessing values, but this is a bit more robust for those certain circumstances.

Trick 3: Implementing you own operator for an object

The +, -, and / are all examples of operators that can be overwritten for your class. For example, let's create a class that you want to add two values objects together to achieve a deterministic result.

With coordinate points, we know you can add two points together to get a new point value. Here, we'll demonstrate that simply by defining the behavior of the + operator.

class Point {
  Point(this.x, this.y);

  final int x;
  final int y;

  /// Sum of two points.
  Point operator +(Point other) => Point(
        this.x + other.x,
        this.y + other.y,
      );
}
Enter fullscreen mode Exit fullscreen mode

This functionality can also be achieved on existing classes with an extension.

extension DateTimeOperators on DateTime {

  /// Date after a [duration] of time.
  DateTime operator +(Duration duration) => this.add(duration);

  /// Difference between [this] duration the [other].
  Duration operator -(DateTime other) => this.difference(other);
}
Enter fullscreen mode Exit fullscreen mode

PS: for a full list of operator that can be used check out this section of Dart's language tour.

Trick 4: Use typedef to keep code concise.

The typedef key word is use to assign a function-type alias to a function.

I have found this most useful in Flutter development when I need to execute a function with a large signature name. For example:

This widget has a long onPressed signature for that member:

class HomePage extends StatelessWidget {
  HomePage(this.onPressed);

  // This is a long signature that can be reduced via typedef.
  final void Function(ViewModel, DateTime) onPressed;

  @override
  Widget build(BuildContext context) {...}
}
Enter fullscreen mode Exit fullscreen mode

But we can keep it concise with typedef:

// Our new signature for this function.
typedef ViewModelCallback = void Function(ViewModel, DateTime);

class HomePage extends StatelessWidget {
  HomePage(this.onPressed);

  // The function member with a new signature.
  final ViewModelCallback onPressed;

  @override
  Widget build(BuildContext context) {...}
}
Enter fullscreen mode Exit fullscreen mode

Trick 5: Use an extension on enum to add more fuctionality

You've already seen an extension used in this list to add functionality, but try using an extension on an enum to give it this little bit of functionality that you need.

enum DayOfTheWeek {
  sunday,
  monday,
  tuesday,
  wednesday,
  thursday,
  friday,
  saturday,
}

extension DayOfTheWeekX on DayOfTheWeek {
  /// The shorthand or abbreviated string of this day of the week.
  String get abbreviation => _abbreviationMap[this]!;

  // a mapping of all the abbreviations
  static const _abbreviationMap = {
    DayOfTheWeek.sunday: 'Sun',
    DayOfTheWeek.monday: 'Mon',
    DayOfTheWeek.tuesday: 'Tue',
    DayOfTheWeek.wednesday: 'Wed',
    DayOfTheWeek.thursday: 'Thur',
    DayOfTheWeek.friday: 'Fri',
    DayOfTheWeek.saturday: 'Sat',
  };
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)