skip to Main Content

I have a login button on my app with this code:

class PublicHomePage extends StatelessWidget {
  const PublicHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    final userDataNotifier = Provider.of<UserDataNotifier>(context);

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            'Please login',
            style: Theme.of(context).textTheme.headlineMedium,
            textAlign: TextAlign.center,
          ),
          const SizedBox(height: 10),
          ElevatedButton(
            onPressed: userDataNotifier.login,
            child: Opacity(
              opacity: userDataNotifier.isLoading ? 0.2 : 1.0,
              child: const Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Icon(Icons.login),
                  SizedBox(width: 10),
                  Text('Login'),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

The UserDataNotifier class is using SharedPreferences in order to save user state. The login function looks like this:

class UserDataNotifier with ChangeNotifier {
  final SharedPreferences prefs;
  bool _isLogged = false;
  bool _isLoading = false;
  UserData? _userData;

  bool get isLogged => _isLogged;
  bool get isLoading => _isLoading;
  UserData? get userData => _userData;

  Future<bool> login() async {
    _isLoading = true;
    notifyListeners();

    var url = Uri.https('mydomain', 'api/login');

    // if there is no internet connection, throw an error
    try {
      var response = await http.get(url);
      var responseBody = response.body;

      // parse response and set user-data (on success)
      // or throw an error (on login failure)

      _isLogged = true;
      _isLoading = false;
      prefs.setBool('isLogged', _isLogged);
      notifyListeners();
      return true;

    } catch (e) {
      _isLoading = false;
      notifyListeners();
      return false;
    }
  }

I want to add en alertDialog if login fails (no internet connection, wrong credentials, etc.)
I tried to add it both on button and inside UserDataNotifier class, but neither works.
How should I add the alert?

2

Answers


  1. use Future function to use the AlertDialog.Refer the below example.
    Call the function whenever you need AlertDialog.

    Future<void> _showMyDialog() async {
      return showDialog<void>(
        context: context,
        barrierDismissible: false, // user must tap button!
        builder: (BuildContext context) {
          return AlertDialog(
            title: const Text('AlertDialog Title'),
            content: const SingleChildScrollView(
              child: ListBody(
                children: <Widget>[
                  Text('This is a demo alert dialog.'),
                  Text('Would you like to approve of this message?'),
                ],
              ),
            ),
            actions: <Widget>[
              TextButton(
                child: const Text('Approve'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        },
      );

    Refer more details on official doc here – AlertDialog

    Login or Signup to reply.
  2. Try below code, update your login() method

    try {
      var response = await http.get(url);
      var responseBody = response.body;
    
     
      if (response.statusCode != 200) {
        _isLoading = false;
        notifyListeners();
        return 'Wrong credentials. Please try again.';
      }
    
      _isLogged = true;
      _isLoading = false;
      prefs.setBool('isLogged', _isLogged);
      notifyListeners();
      return null;
    } catch (e) {
      _isLoading = false;
      notifyListeners();
      return 'No internet connection. Please try again later.';
    }
    

    Your onPressed function.

     onPressed: () async {
              String? errorMessage = await userDataNotifier.login();
              if (errorMessage != null) {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('Login Failed'),
                    content: Text(errorMessage),
                    actions: [
                      TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: Text('OK'),
                      ),
                    ],
                  ),
                );
              }
            },
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search