Riverpod code generator problem . State is not getting updated in one page , but is getting updated in another

46 Views Asked by At

This is my customTextFiled , that has some arguments . Here , the "func" is used to call the "onChanged" of the TextField widget in flutter. I am using riverpod state management with riverpod code generator .

appTextField(
  text: "Username",
  icon: "assets/icons/user.png",
  hintText: "Enter your username",
  func: (value) {
    ref
      .read(registerNotifierProvider.notifier)
      .onUserNameChanged(value);
      print(ref.watch(registerNotifierProvider).userName);
    },
  ),

Here when i m updating the state using "ref.read" and printing it, i m getting this in the debug console.

I/flutter ( 6399): a
I/flutter ( 6399): as
I/flutter ( 6399): asd
I/flutter ( 6399): asds
I/flutter ( 6399): your name is : 

Here , "your name is:" is printing when i am pressing a button on the same page , printing the state of the (registerNotifierProvider).userName This is the problem .At one stage of the build the RegisterState is updated and then again a new instance of the class is created making the state variables to null .I am not able to do userAuthentication because of this . This is my RegisterNotifier , that i m using to generate the registerNotifierProvider

import 'package:elearningapp/pages/register_page/notifier/register_state.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'register_notifier.g.dart';

@riverpod
class RegisterNotifier extends _$RegisterNotifier {
  @override
  RegisterState build() {
    return RegisterState();
  }

  void onUserNameChanged(String name) {
    state = state.copyWith(userName: name);
  }

  void onUserEmailChanged(String email) {
    state = state.copyWith(email: email);
  }

  void onUserPasswordChanged(String password) {
    state = state.copyWith(password: password);
  }

  void onUserRePasswordChanged(String repassword) {
    state = state.copyWith(repassword: repassword);
  }
}

And this is my RegisterState class

class RegisterState {
  final String userName;
  final String email;
  final String password;
  final String repassword;

  RegisterState({
    this.userName = "",
    this.email = "",
    this.password = "",
    this.repassword = "",
  });

  RegisterState copyWith({
    String? userName,
    String? email,
    String? password,
    String? repassword,
  }) {
    return RegisterState(
      userName: userName ?? this.userName,
      email: email ?? this.email,
      password: password ?? this.password,
      repassword: repassword ?? this.repassword,
    );
  }
}

This is my SignUpController , that i am using to handle signIn .it is called when i press the registerButton

import 'package:elearningapp/pages/register_page/notifier/register_notifier.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class SingUpController {
  final WidgetRef ref;

  SingUpController({required this.ref});

  void handleSignUp() {
    var state = ref.watch(registerNotifierProvider);

    String name = state.userName;
    String email = state.email;
    String password = state.password;
    String rePassword = state.repassword;

    print("your name is : $name");
    
    // print("pass: $password");
    // print("repss; $rePassword");
  }
}

Thanks for the response.

This is the most stupid part . At times when i rebuild the app and provide input , the whole app works for some time like state is updated and printing properly , but after few updates it again stop responding . I am new to code generator , am i doing something wrong .

1

There are 1 best solutions below

0
On

The problem is as simple as possible: you should not use ref.watch outside of widget build locations or providers.

So once:

appTextField(
  text: "Username",
  icon: "assets/icons/user.png",
  hintText: "Enter your username",
  func: (value) {
    ref
      .read(registerNotifierProvider.notifier)
      .onUserNameChanged(value);
      print(ref.read(registerNotifierProvider).userName);
    }, // here >----<
  ),

Two:

class SingUpController {
  final WidgetRef ref;

  SingUpController({required this.ref});

  void handleSignUp() {
    //        here >----<
    var state = ref.read(registerNotifierProvider);

    String name = state.userName;
    String email = state.email;
    String password = state.password;
    String rePassword = state.repassword;

    print("your name is : $name");
  }
}

Moreover, you should reconsider the architecture of your SingUpController. Passing arguments to WidgetRef is a bad idea.