skip to Main Content

I’m trying to do authentication using Riverpod StateNotifier and FutureProvider but I’m facing error when using when method facing this error

The method ‘when’ can’t be unconditionally invoked because the receiver can be ‘null’.
Try making the call conditional (using ‘?.’) or adding a null check to the target (‘!’).

even when adding ! it shows this

The method ‘when’ isn’t defined for the type ‘Object’.⏎Try correcting the name to the name of an existing method, or defining a method named ‘when’.

class MainPage extends ConsumerWidget {
  const MainPage({super.key});
  @override
  Widget build(BuildContext context, WidgetRef ref) {
  final state = ref.watch(emailPasswordSignInControllerProvider);

  return state.when(
    data: (state) {
      return state == AuthState.authenticated
          ? const SharedLayout()
          : const LoginScreen();
    },
    error: (error, stackTrace) => const Scaffold(
      body: Center(child: Text("Error")),
    ),
    loading: () => const Scaffold(
      body: Center(
        child: CircularProgressIndicator(),
      ),
    ),
  );

here is controller:

class EmailPasswordSignInController extends StateNotifier<AsyncValue<AuthState>> {
  EmailPasswordSignInController({required this.authRepository})
      : super(const AsyncValue.data(AuthState.notAuthenticated));
  final AuthRepository authRepository;

  Future<void> submit(String email, String password) async {
    try {
      state = const AsyncValue.loading();
      await authRepository.signInWithEmailAndPassword(email, password);
      state = const AsyncValue.data(AuthState.authenticated);
    } catch (e, st) {
      state = AsyncValue.error(e, st);
    }
  }
}

final emailPasswordSignInControllerProvider = StateNotifierProvider((ref) {
  final authRepository = ref.watch(authRepositoryProvider);
  return EmailPasswordSignInController(authRepository: authRepository);
});

And this is my repository:

class AuthRepository {
  Future<String> signInWithEmailAndPassword(
    String email, 
    String password,
  ) async {
    try {
      final String token;
      final Map<String, dynamic> jsonData;
      final url = Uri.parse('http://192.168.1.9:5000/api/v1/auth/login');
      final response = await http.post(url,
          body: jsonEncode({
            "email": email,
            "password": password,
          }),
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          });
      jsonData = jsonDecode(response.body);
      if (response.statusCode == 200) {
        token = jsonData['token'];
        return token;
      }
      return "error";
    } on Exception catch (e) {
      print(e.toString());
      return e.toString();
    }
  }
}

final authRepositoryProvider = Provider<AuthRepository>((ref) {
  return AuthRepository();
});

3

Answers


  1. Chosen as BEST ANSWER

    this fixed the error:

        StateNotifierProvider<EmailPasswordSignInController, AsyncValue>((ref) {
      final authRepository = ref.watch(authRepositoryProvider);
      return EmailPasswordSignInController(authRepository: authRepository);
    });
    

  2. The error is saying that state where you define it by final state = ref.watch(emailPasswordSignInControllerProvider); could return a null value. So you can add a null check operator there if you’re sure that it won’t return null

    final state = ref.watch(emailPasswordSignInControllerProvider)!;
    

    Or instead you can call it conditionally so that if state is returning a null value, it wont perform the .when:

    return state?.when
    

    You also need to define the type of your provider like this:

    final emailPasswordSignInControllerProvider = StateNotifierProvider<EmailPasswordSignInController, AsyncValue<AuthState>>( (ref)
    
    Login or Signup to reply.
  3.  final state = ref.watch(emailPasswordSignInControllerProvider) ?? "";
    

    try using that it will work,or use in that

    final state = ref.watch(emailPasswordSignInControllerProvider ?? "");
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search