0

I am developing authentication for my flutter app. Please help me to resolve the issue. I am unable to identify the problem which returns such an error stating Unhandled Exception: type 'List' is not a subtype of type 'String'.

Here is the code for the login screen:

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class WelcomeBackPage extends StatefulWidget {
  @override
  WelcomeBackPageState createState() => WelcomeBackPageState();
}

class WelcomeBackPageState extends State<WelcomeBackPage> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  final _formKey = GlobalKey<FormState>();
  bool _isSubmitting, _obscureText = true;
  String _email, _password;

  Widget _showHello() {
    return Text(
      'Hello',
      style: GoogleFonts.montserrat(
          fontSize: 70.0,
          fontWeight: FontWeight.w800,
          textStyle: TextStyle(color: Colors.black)),
    );
  }

  Widget _showThere() {
    return Container(
        padding: EdgeInsets.only(left: 5.0),
        child: Text(
          'There',
          style: GoogleFonts.montserrat(
              fontSize: 70.0,
              fontWeight: FontWeight.w800,
              height: 0.7,
              textStyle: TextStyle(color: Colors.black)),
        ));
  }

  Widget _showDot() {
    return Text(
      '.',
      style: GoogleFonts.montserrat(
          fontSize: 70.0,
          fontWeight: FontWeight.bold,
          height: 0.7,
          textStyle: TextStyle(color: Colors.green)),
    );
  }

  Widget _showEmailInput() {
    return Padding(
        padding: EdgeInsets.only(top: 30.0, left: 5.0),
        child: TextFormField(
          onSaved: (val) => _email = val,
          decoration: InputDecoration(
            labelText: 'EMAIL',
            labelStyle: TextStyle(
                fontFamily: 'Montserrat',
                fontWeight: FontWeight.bold,
                color: Colors.grey),
            enabledBorder: UnderlineInputBorder(
              borderSide: BorderSide(color: Colors.grey[300]),
            ),
            focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.green)),
          ),
          keyboardType: TextInputType.emailAddress,
          validator: (val) => !val.contains('@') ? 'Invalid Email' : null,
        ));
  }

  Widget _showPasswordInput() {
    return Padding(
        padding: EdgeInsets.only(top: 10.0, left: 5.0),
        child: TextFormField(
          onSaved: (val) => _password = val,
          decoration: InputDecoration(
            suffixIcon: GestureDetector(
                onTap: () {
                  setState(() => _obscureText = !_obscureText);
                },
                child: Icon(
                    _obscureText ? Icons.visibility : Icons.visibility_off)),
            labelText: 'PASSWORD',
            labelStyle: TextStyle(
                fontFamily: 'Montserrat',
                fontWeight: FontWeight.bold,
                color: Colors.grey),
            enabledBorder: UnderlineInputBorder(
              borderSide: BorderSide(color: Colors.grey[300]),
            ),
            focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.green)),
          ),
          obscureText: _obscureText,
          validator: (val) => val.length < 6 ? 'Invalid Password' : null,
        ));
  }

  Widget _showForgotPassword() {
    return Container(
        alignment: Alignment(1.2, 0.0),
        child: Padding(
          padding: EdgeInsets.only(top: 0.0),
          child: Column(
            children: <Widget>[
              FlatButton(
                onPressed: () {},
                child: Text(
                  'Forgot Password',
                  style: GoogleFonts.montserrat(
                      color: Colors.green,
                      fontSize: 16.0,
                      fontWeight: FontWeight.bold,
                      decoration: TextDecoration.underline),
                ),
              ),
            ],
          ),
        ));
  }

  Widget _showLogin() {
    return Padding(
        padding: EdgeInsets.only(top: 20.0),
        child: ButtonTheme(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(100)),
            child: Center(
                child: _isSubmitting == true
                    ? CircularProgressIndicator(
                        valueColor: AlwaysStoppedAnimation(Colors.green),
                      )
                    : RaisedButton(
                        onPressed: _login,
                        textColor: Colors.white,
                        color: Colors.green,
                        padding: EdgeInsets.all(5.0),
                        child: Container(
                          height: 50,
                          width: MediaQuery.of(context).size.width,
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(100),
                              color: Colors.green),
                          padding: const EdgeInsets.all(15.0),
                          child: Text(
                            'LOGIN',
                            textAlign: TextAlign.center,
                            style: GoogleFonts.montserrat(
                              letterSpacing: 2.0,
                              fontSize: 18.0,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ),
                      ))));
  }

  void _login() {
    final form = _formKey.currentState;

    if (form.validate()) {
      form.save();
      _registerUser();
    }
  }

  void _registerUser() async {
    setState(() => _isSubmitting = true);
    http.Response response = await http.post(
        'http://192.168.43.9:1337/auth/local',
        body: {"identifier": _email, "password": _password});
    final responseData = json.decode(response.body);
    if (response.statusCode == 200) {
      setState(() => _isSubmitting = false);
      _showSuccessSnack();
      _redirectUser();
      print(responseData);
    } else {
      setState(() => _isSubmitting = false);
      final String errorMsg = responseData['message'];
      _showErrorSnack(errorMsg);
    }
  }

  void _showSuccessSnack() {
    final snackbar = SnackBar(
        content: Text(' User successfully logged in ',
            style:
                GoogleFonts.montserrat(color: Colors.green, fontSize: 16.0)));
    _scaffoldKey.currentState.showSnackBar(snackbar);
    _formKey.currentState.reset();
  }

  void _showErrorSnack(String errorMsg) {
    final snackbar = SnackBar(
        content: Text(errorMsg,
            style: GoogleFonts.montserrat(color: Colors.red, fontSize: 16.0)));
    _scaffoldKey.currentState.showSnackBar(snackbar);
    throw Exception('Error logging in: $errorMsg');
  }

  void _redirectUser() {
    Future.delayed(Duration(seconds: 2), () {
      Navigator.pushReplacementNamed(context, '/intro');
    });
  }

  Widget _showGoogle() {
    return Padding(
        padding: EdgeInsets.only(top: 20.0),
        child: OutlineButton(
          shape: StadiumBorder(),
          textColor: Colors.black,
          borderSide: BorderSide(
              color: Colors.black, style: BorderStyle.solid, width: 2.5),
          onPressed: () {},
          padding: EdgeInsets.all(5.0),
          child: Container(
            height: 50,
            width: MediaQuery.of(context).size.width,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Center(
                  child: ImageIcon(AssetImage('assets/facebook.png')),
                ),
                SizedBox(width: 10.0),
                Center(
                  child: Text(
                    'Log in with Google',
                    textAlign: TextAlign.center,
                    style: GoogleFonts.montserrat(
                      fontSize: 18.0,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                )
              ],
            ),
          ),
        ));
  }

  Widget _showNewRegister() {
    return Padding(
        padding: EdgeInsets.only(top: 35.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'New to Oristore ?',
              style: GoogleFonts.montserrat(
                fontSize: 16.0,
                fontWeight: FontWeight.w600,
              ),
            ),
            SizedBox(width: 5.0),
            InkWell(
              onTap: () => Navigator.pushReplacementNamed(context, '/register'),
              child: Text(
                'Register',
                style: GoogleFonts.montserrat(
                  fontSize: 17.0,
                  color: Colors.green,
                  fontWeight: FontWeight.w600,
                  decoration: TextDecoration.underline,
                ),
              ),
            )
          ],
        ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        key: _scaffoldKey,
        resizeToAvoidBottomPadding: false,
        resizeToAvoidBottomInset: true,
        body: SingleChildScrollView(
            child: Form(
                key: _formKey,
                child: Stack(children: <Widget>[
                  Container(
                      padding: EdgeInsets.symmetric(horizontal: 20.0),
                      child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            SizedBox(
                              height: 60.0,
                            ),
                            Padding(
                                padding: EdgeInsets.all(10.0),
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    _showHello(),
                                    new Row(children: <Widget>[
                                      _showThere(),
                                      _showDot(),
                                    ]),
                                    _showEmailInput(),
                                    _showPasswordInput(),
                                    _showForgotPassword(),
                                    _showLogin(),
                                    _showGoogle(),
                                    _showNewRegister()
                                  ],
                                ))
                          ])),
                  //_showOTPAction(),
                ]))));
  }
}


Section of above code to perform Login:

    void _login() {
            final form = _formKey.currentState;
        
            if (form.validate()) {
              form.save();
              _registerUser();
            }
          }
        
          void _registerUser() async {
            setState(() => _isSubmitting = true);
            http.Response response = await http.post(
                'http://192.168.43.9:1337/auth/local',
                body: {"identifier": _email, "password": _password});
            final responseData = json.decode(response.body);
            if (response.statusCode == 200) {
              setState(() => _isSubmitting = false);
              _showSuccessSnack();
              _redirectUser();
              print(responseData);
            } else {
              setState(() => _isSubmitting = false);
              final String errorMsg = responseData['message'];
              _showErrorSnack(errorMsg);
            }
          }
        
          void _showSuccessSnack() {
            final snackbar = SnackBar(
                content: Text(' User successfully logged in ',
                    style:
                        GoogleFonts.montserrat(color: Colors.green, fontSize: 16.0)));
            _scaffoldKey.currentState.showSnackBar(snackbar);
            _formKey.currentState.reset();
          }
        
          void _showErrorSnack(String errorMsg) {
            final snackbar = SnackBar(
                content: Text(errorMsg,
                    style: GoogleFonts.montserrat(color: Colors.red, fontSize: 16.0)));
            _scaffoldKey.currentState.showSnackBar(snackbar);
            throw Exception('Error logging in: $errorMsg');
          }
        
          void _redirectUser() {
            Future.delayed(Duration(seconds: 2), () {
              Navigator.pushReplacementNamed(context, '/intro');
            });
          }

Error

E/flutter ( 4862): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'String'
E/flutter ( 4862): #0      WelcomeBackPageState._registerUser (package:oristore/screens/auth/welcome_back_page.dart:182:20)
E/flutter ( 4862): <asynchronous suspension>
E/flutter ( 4862): #1      WelcomeBackPageState._login (package:oristore/screens/auth/welcome_back_page.dart:165:7)
E/flutter ( 4862): #2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
E/flutter ( 4862): #3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
E/flutter ( 4862): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
E/flutter ( 4862): #5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
E/flutter ( 4862): #6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
E/flutter ( 4862): #7      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:219:7)
E/flutter ( 4862): #8      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:477:9)
E/flutter ( 4862): #9      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:78:12)
E/flutter ( 4862): #10     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:124:9)
E/flutter ( 4862): #11     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
E/flutter ( 4862): #12     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:122:18)
E/flutter ( 4862): #13     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:108:7)
E/flutter ( 4862): #14     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:220:19)
E/flutter ( 4862): #15     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
E/flutter ( 4862): #16     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
E/flutter ( 4862): #17     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
E/flutter ( 4862): #18     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
E/flutter ( 4862): #19     _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 4862): #20     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4862): #21     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 4862): #22     _invoke1 (dart:ui/hooks.dart:267:10)
E/flutter ( 4862): #23     _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
E/flutter ( 4862):
   
3
  • Does this help? What is a NoSuchMethod error and how do I fix it? Commented Oct 1, 2020 at 5:14
  • I am unable to locate the String or list or something which is causing the error. Therefore help me resolve it on my code. Commented Oct 1, 2020 at 5:31
  • Please see _registerUser(). Are you sure that responseData['message'] in final String errorMsg = responseData['message']; is String and not a List of messages? Commented Oct 1, 2020 at 11:13

2 Answers 2

0

Try this val?.length to make val nullable.

Sign up to request clarification or add additional context in comments.

2 Comments

please suggest the full line of code to be modified.
I found the solution long back but failed to indicate it as comment. It is below as an answer. Thank you
0

onSaved: (val) => _email = val, onSaved: (val) => _password = val,

should be added in the textformfield input so that the val doesnt return to be null.

Restarting the server api with the entire flutter app solved the problem. Now a user can be successfully Logged in.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.