GrandMagus
GrandMagus

Reputation: 742

Riverpod Notifer for multiple Widgets of the same type

I'm trying out Riverpod and I'm having difficulty understanding some of the things in it. In BloC, when you wrap a widget with a Bloc and you map out a list of widgets, you get 5 instances of Blocs but it seems it is not the same with Riverpod, you only get one and when you change one value, it changes for all elements. Example:

Notifier:

import 'package:flutter_riverpod/flutter_riverpod.dart';

class BasicBoolNotifier extends Notifier<SomeData> {
  @override
  SomeData build() {
    return SomeData();
  }

  //update values onPressButton
  void updateValue(String element, bool value) {
    if (element == "Text1") {
      state = state.copyWith(value1: value);
    } else if (element == "Text2") {
      state = state.copyWith(value2: value);
    } else if (element == "Text3") {
      state = state.copyWith(value3: value);
    }
  }


  //read the current state of the element so i know the bool value for that element
  bool getValue(String element) {
    if (element == "Text1") {
      return state.value1;
    } else if (element == "Text2") {
       return state.value2;
    }else if (element == "Text3") {
       return state.value3;
    }
    return false;
  }
}

final boolNotifierProvider =
    NotifierProvider<BasicBoolNotifier, SomeData>(BasicBoolNotifier.new);

class SomeData{
  final bool value1;
  final bool value2;
  final bool value3;

  SomeData({
    this.value1 = false,
    this.value2 = false,
    this.value3 = false,
  });

  SomeData copyWith({
    bool? value1,
    bool? value2,
    bool? value3,
  }) {
    return SomeData(
      value1: value1 ?? this.value1,
      value2: value2 ?? this.value2,
      value3: value3 ?? this.value3,
    );
  }
}

Screen and on button press:

// the class extends ConsumerWidget
final notifier = ref.watch(boolNotifierProvider.notifier);

Column(
  children: [
    'Text1',
    'Text2',
    'Text3',
  ].map((e) {
    final bool value = notifier.getValue(e);
    return Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(e),
          InkWell(
            onTap: () {
              notifier.updateValue(e, !value);
            
            },
          ),
      //based on the condition of the element value, return text
          value ? Text('On') : Text('Off'),
         ],
       );

is there something I'm missing? I want to change only the value of one element in the list, not all of them... Can this be done in Riverpod with one provider and not making 3 separate provders for 3 separate values? Thank you advance for you help!

Upvotes: 0

Views: 54

Answers (1)

Randal Schwartz
Randal Schwartz

Reputation: 44186

That's what family notifiers/providers are for. Multiple providers that share common code that are distinguished by a family key. See the docs at https://riverpod.dev/docs/essentials/passing_args

Upvotes: 1

Related Questions