1

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())),
    );
  }
}

MohaAmiry
  • 21
  • 1
  • Your `CounterState1` is not something Riverpod recommends. Riverpod would recommend subclassing `StateNotifier`/`Notifier`. See https://riverpod.dev/docs/providers/state_notifier_provider – Rémi Rousselet Jan 04 '23 at 14:02
  • I know, i did it this way because i want to grasp how to work with stream provider. just in case i wanted to add a value to a stream through user input for some reason. so how to emit a value to a stream provider? – MohaAmiry Jan 04 '23 at 14:12
  • 1
    The problem is unrelated to StreamProvider. It's the stream returned by `counterStream()` that is incorrect. It's only emitting one event. You probably want some StreamController and call `controller.add` – Rémi Rousselet Jan 04 '23 at 15:14

0 Answers0