🌊Stream data

Stream provides you a sequence of data. It can become memory leaks, if you don't dispose them correctly.

Use tip: At first, you'll have to install Pulse-X package. Here's the installation tip.

Usage

Stream data management is difficult. With Pulse-X, you won't have to use StreamController or Stream, or listen to StreamController. Pulse-X provides you with PulseXStreamViewModel class that you can extend and PulseXStreamBuilder for reactive UI.

Now, we'll create a realtime clock project that uses Stream data with Pulse-X.

First, you'll need to install intl package to convert date format.

Then, start creating a TimerViewModel class like this.

class TimerViewModel extends PulseXStreamViewModel<String> { // specify stream data type
  late Timer _timer;
  final DateFormat formattedDate = DateFormat('h:mm:ss a'); // convert date format
  void addDateTime() {
    _timer = Timer.periodic(
      const Duration(seconds: 1),
          (timer) {
        String currentTime = formattedDate.format(DateTime.now());
        addValue(currentTime); // Pulse will automatically add data via sink 
      },
    );
  }

  @override
  void onDispose() {
    _timer.cancel(); // cancel your timer or it'll probably make memory leak
  }
}

See! You don't even use stream here. Because Pulse is handling Stream automatically.

Then, it's time to create TimerView class.

final amber500 = Colors.amber.shade500;

class TimerView extends StatefulWidget {
  const TimerView({Key? key}) : super(key: key);

  @override
  State<TimerView> createState() => _TimerViewState();
}

class _TimerViewState extends State<TimerView> {
  final timerViewModel = TimerViewModel(); // create timer view model
  @override
  void initState() {
    super.initState();
    timerViewModel.addDateTime(); // add stream data
  }

  @override
  void dispose() {
    timerViewModel.onDispose(); // dispose view model to cancel timer
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Timer'),
      ),
      body: Center(
        child: PulseXStreamBuilder( // for reactive UI
          viewModel: timerViewModel,
          builder: (_, viewModel, snapshot) { // three parameters -context,view model, snapshot
            // you have to use snapshot to retrieve stream data
            if (snapshot.hasData) {
              return TimerLabel(time: snapshot.data.toString());
            } else if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            return CupertinoActivityIndicator(
              radius: 20,
              color: amber500,
            );
          },
        ),
      ),
    );
  }
}

class TimerLabel extends StatelessWidget {
  const TimerLabel({Key? key, required this.time}) : super(key: key);
  final String time;
  @override
  Widget build(BuildContext context) {
    return Text(
      time,
      style: Theme.of(context).textTheme.displayLarge?.copyWith(
        color: amber500,
      ),
    );
  }
}

😎 Ez done!!

Complete source code can be found here. https://github.com/YeLwinOo-Steve/stream_time

Last updated