Home > Enterprise >  How to navigate to another page after using a provider function in flutter?
How to navigate to another page after using a provider function in flutter?

Time:04-15

I have created a function in my Login provider to verify OTP for my app like below.

Future<bool> verifyOtp(String otp) async {
    final _loginData = await SharedPreferences.getInstance();

    _isLoading = true;
    notifyListeners();
    _status = await AuthApi.verifyOtp(otp);
    _isLoading = false;
    _name = _loginData.getString('name');
    notifyListeners();
    return _status;
  }

Now whenever I am trying to use this on my code like below,

final bool status = await Provider.of<LoginProvider>(context, listen: false).verifyOtp(verificationCode);

// ignore: avoid_print
print("STATUS ==== "   status.toString());
if (status) {
  Navigator.of(context).pushReplacementNamed('/discover');
} else {
  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Incorrect OTP!!!")));
}

It's giving me an exception like below -

Exception has occurred.
FlutterError (This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.)

Anyone please guide me, what is the actual way to navigate from a provider. I am very new in Provider. Thank you so much :)

----- Full Provider Code is Below -----

class LoginProvider with ChangeNotifier {
  bool _status = false;
  bool _isLoading = false;
  bool _isOtpScreen = false;
  String? _name;

  bool get isLoading => _isLoading;
  bool get isOtpScreen => _isOtpScreen;
  String? get name => _name;

  void sendOtp(String phone) async {
    _isLoading = true;
    notifyListeners();
    _status = await AuthApi.sendOtp(phone);
    _isLoading = false;
    _isOtpScreen = true;
    notifyListeners();
  }

  Future<bool> verifyOtp(String otp) async {
    final _loginData = await SharedPreferences.getInstance();

    _isLoading = true;
    notifyListeners();
    _status = await AuthApi.verifyOtp(otp);
    _isLoading = false;
    _name = _loginData.getString('name');
    notifyListeners();
    return _status;
  }
}

CodePudding user response:

Use a GlobalKey you can access from anywhere to navigate

Create the key

final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
void main() async {
 WidgetsFlutterBinding.ensureInitialized();
   runApp(MyApp());
}

Pass it to your App:

new MaterialApp(
  title: 'MyApp',
  onGenerateRoute: generateRoute,
  navigatorKey: navigatorKey,
);

Use in your route:

    print("STATUS ==== "   status.toString());
    if (status) {
       Navigator.of(navigatorKey.currentContext).pushReplacementNamed('/discover');
    } else {
      ScaffoldMessenger.of(navigatorKey.currentContext).showSnackBar(const SnackBar(content:
      Text("Incorrect OTP!!!")));
    }

CodePudding user response:

final bool status = await Provider.of<LoginProvider>(context, listen: false).verifyOtp(verificationCode);

// ignore: avoid_print
print("STATUS ==== "   status.toString());
if (status) {
  Navigator.of(context).pushReplacementNamed('/discover');
} else {
  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Incorrect OTP!!!")));
}

change this code to the next one and i think it will work but you must add this code in build function if it's stateless widget

final provider = Provider.of<LoginProvider>(context);

final status = await provider.verifyOtp(verificationCode);

// ignore: avoid_print
print("STATUS ==== "   status.toString());
if (status) {
  Navigator.of(context).pushReplacementNamed('/discover');
} else {
  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Incorrect OTP!!!")));
}

this will work fine with you i hope it help you

  • Related