# Stream data

{% hint style="info" %}
**Use tip:** At first, you'll have to install **Pulse-X** package. Here's [the installation tip.](https://ye-lwin-oo-1.gitbook.io/pulse-x-state-management/pulse-x-overview/use-tip)
{% endhint %}

## 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.

{% hint style="info" %}
First, you'll need to install `intl` package to convert date format.
{% endhint %}

Then, start creating a `TimerViewModel` class like this.

```dart
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
  }
}
```

<mark style="background-color:green;">See! You don't even use stream here</mark>. Because Pulse is handling Stream automatically.

Then, it's time to create `TimerView` class.

```dart
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!!&#x20;

{% hint style="success" %}
Complete source code can be found here. <https://github.com/YeLwinOo-Steve/stream_time>
{% endhint %}
