Search code examples
flutterdart

Flutter add AlertDialog to ElevatedButton.onPressed


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?


Solution

  • 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'),
                      ),
                    ],
                  ),
                );
              }
            },