Flutter-Dart Tips & Tricks - Part 1

Flutter-Dart Tips & Tricks - Part 1

Exploring the Uncharted Territory of Flutter and Dart: 7 Days of Hidden Gems for the Savvy Developer

ยท

3 min read

  1. Using isolates for concurrency:

    Dart's isolate system allows you to run multiple independent "isolated" threads of execution within a single Dart process. You can use isolates to perform CPU-intensive tasks without blocking the main UI thread, improving your app's responsiveness and performance.

    Example:

import 'dart:isolate';

void main() async {
  final receivePort = ReceivePort();
  final isolate = await Isolate.spawn(doHeavyWork, receivePort.sendPort);
  receivePort.listen((data) => print('Result: $data'));
}

void doHeavyWork(SendPort sendPort) {
  // Perform some CPU-intensive work here
  final result = 1 + 2 + 3 + 4 + 5;
  print('Result from Heavy Work: $result');
  sendPort.send(result);
}
  1. Wait for the results of multiple Futures together:

    Returns a future that will complete once all the provided futures have completed, either with their results or with an error if any of the provided futures fail.

    Example:

class SomeAPI {
  Future<String> getThings() => Future.value('Hello');
  Future<int> getItems() => Future.value(300);
  Future<int> getStuff() => Future.value(30);
}

void main() async {
  final api = SomeAPI();
  final values = await Future.wait([
    api.getThings(),
    api.getItems(),
    api.getStuff(),
  ]);
  print('Here is the output: $values');
}
  1. A more effective way to use 'Future.wait()' with asynchronous programming:

    In this example, we use closures (anonymous functions) to simplify asynchronous operations. The getUserData function uses the await keyword to wait for a fetchUserData function to complete and return a user object. Then, it returns the user's name.

    The getUserNames function takes a list of user IDs, maps them to getUserData functions using a closure, and uses Future.wait to wait for all the functions to complete. Finally, it maps the user data to their names and returns a list of names. This is a concise and readable way to handle asynchronous operations with multiple dependent calls.

Future<String> getUserData(int userId) async {
  final userData = await fetchUserData(userId);
  return userData.name;
}

Future<List<String>> getUserNames(List<int> userIds) async {
  final userFutures = userIds.map((id) => getUserData(id));
  final userData = await Future.wait(userFutures);
  return userData.map((data) => data.name).toList();
}
  1. typedef for Functions:

    In Dart 1, If you want to utilize a function as a variable, field, or boundary, you have to make a typedef first.

    Example:

typedef EvenFilter = bool Function(int);

void main() {
  final list = [1, 2, 3, 4, 5];
  final evenFilter = (int n) => n % 2 == 0;
  final evenNumbers = list.where(evenFilter);
  print(evenNumbers);
}
  1. typedef for Non-functions:

    With Dart 2.13, typedefs can be now used to create type aliases that refer to non-functions.

    Example:

typedef IntList = List<int>;

void main() {
  IntList data = [50, 60];
  data.add(100);
  print('length: ${data.length}');
  print('values: $data');
  print('type: ${data.runtimeType}');
}

// Output will be
length: 3
values: [50,60,100]
type: List<int>

And that's it for our first installment of Flutter tips and tricks! I hope you learned something new and useful that will help you build better and more efficient apps. ๐Ÿ˜Ž

Stay tuned for more articles in this series where I'll share more hidden gems and advanced techniques that will take your Flutter skills to the next level. ๐Ÿฅ

If you have any feedback, questions or suggestions for future topics, feel free to reach out to me on Twitter or LinkedIn. We'd love to hear from you and see what you're building with Flutter! ๐Ÿค– ๐Ÿ’ป ๐Ÿš€

Follow me on Twitter ๐Ÿฆ or Connect with me on LinkedIn ๐ŸŽ‰

Did you find this article valuable?

Support Pratik Butani by becoming a sponsor. Any amount is appreciated!

ย