Flutter Riverpod 2.0 - how to emit (add) a value to a stream provider manually (through user input)?

899 Views Asked by At

i'm learning riverpod but i'm facing alot of problems because the lack of examples.

i have the following:

  • a class called CounterState1 which contains a stream that emits an integer.
  • a provider for CounterState1.
  • a stream provider for CounterState1().Stream.

i want to emit a value to the stream through user intercation e.g. (a button click to emit an integer to the stream). in plain old streams we used stream controllers with sinks and listeners for user interactions.

i want to achieve the same goal Riverpod streams provider. i know i can do this task with stateNotifier. but i want it to be done with streams.

i wrote a simple code to demonstrate what supposed to happen:

class CounterState1{
  int counter;

  CounterState1(this.counter);

  Stream<int> counterStream () async* {
    yield counter;
  }

  // this method here increments a the value that is supposed to emit to stream.
  // this could have been done with `CounterStreamController.sink(++counter);`
  void incStreamVal() => counter++;
}
final counterState1Provider = Provider((ref) => CounterState1(1));

final streamCounterProvider = StreamProvider((ref) {
  var str = ref.read(counterState1Provider).counterStream();
  return str;
});

class IncrementerView2 extends ConsumerWidget {
  const IncrementerView2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    AsyncValue<int> asyncVal = ref.watch(streamCounterProvider);

    return Scaffold(
      appBar: AppBar(title: const Text("Incrementer")),
      body: Center(
          child: asyncVal.when(
              data: (data) => Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Text(asyncVal.value.toString(),
                          style: const TextStyle(fontSize: 30)),
                      Column(
                        children: [
                          ElevatedButton(
                              onPressed: () {
                                // when clicking here it is supposed to add a value to
                                // the sink of the stream.
                                ref.read(counterState1Provider).incStreamVal();
                              },
                              child: const Text("inc First")),
                        ],
                      ),
                    ],
                  ),
              error: (error, stackTrace) => Text(error.toString()),
              loading: () => const CircularProgressIndicator())),
    );
  }
}

0

There are 0 best solutions below