未处理的异常:NoSuchMethodError:在null上调用了getter'text'

时间:2020-09-10 14:08:12

标签: flutter dart

好吧,我正在使用提供程序。...。方法名称为createResgister,所以这是返回包含响应的Future的方法。好的,并且我想要发布的每种表单都有TextEdittingController,我也想要发布的api

然后,我创建了两个方法passRegister()和registerFom():因此registerForm将在_futureRegister .....内部注册TextFormField。passRegister将createRegister分配给_futureRegister .....我真的不知道是否逻辑是合理的..

`import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:logistics_app/models/registerApi.dart';
import 'package:logistics_app/ui/dashboard_view.dart';
import 'package:logistics_app/utils/validation.dart';
import 'package:http/http.dart' as http;

import '../ui/login_view.dart';



class UserOnboardingModel extends ChangeNotifier with ValidationMixin{

  TextEditingController firstController;
  TextEditingController lastController;
  TextEditingController passwordController;
  TextEditingController emailController;
  TextEditingController phoneController;
  bool showPassword = true;

  final formKey = GlobalKey<FormState>();

  Future<RegisterModel> _futureRegister;

  Future<RegisterModel> createRegister()async{
    final http.Response response = await http.post(
        "apiKey",
        body: jsonEncode(<String, String>{
          'firstName' : validateFirstName(firstController.text),
          'lastName' : validateLastName(lastController.text),
          'emailAddress' : validateEmail(emailController.text),
          'phoneNumber' : validatePhoneNumber(phoneController.text),
          'password' : validatePassword(passwordController.text)
        })
    );
    if(response.statusCode == 201){
      return RegisterModel.fromJson(json.decode(response.body));
    }else{
      throw Exception('Failed to create Register');
    }
  }

  void passRegister(){
    _futureRegister = createRegister();
  }

  void registerForm(){
    FutureBuilder<RegisterModel>(
      future: _futureRegister,
      builder: (context, snapshot){
        if(snapshot.hasData){
          return Column(
            children: [
              Text(snapshot.data.firstName),
              Text(snapshot.data.lastName),
              Text(snapshot.data.emailAddress),
              Text(snapshot.data.phoneNumber),
              Text(snapshot.data.password)
            ],
          );
        }else if(snapshot.hasError){
          return Text("${snapshot.error}");
        }
        return CircularProgressIndicator();
      },
    );
  }

  void togglePassword(){
    showPassword = !showPassword;
    notifyListeners();
  }

  void validateForm(){
    formKey.currentState.validate();
  }

  void moveToLogin(context){
    //go to login page
    if(formKey.currentState.validate()){
      Navigator.pushNamed(context, LogIn.LOG_IN_ROUTE);
    }
    else{
      Fluttertoast.showToast(
          msg: "Please Fill The Form",
          toastLength: Toast.LENGTH_LONG,
          gravity: ToastGravity.BOTTOM,
        timeInSecForIosWeb: 5,
        backgroundColor: Colors.black,
      );
    }
  }

  void moveToDashBoardView(context){
    //go to login page
    if(formKey.currentState.validate()){
      Navigator.push(context, MaterialPageRoute(
          builder: (context) => DashboardView()
      ));
    }
    else{
      Fluttertoast.showToast(
        msg: "Please Fill The Form",
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
        timeInSecForIosWeb: 5,
        backgroundColor: Colors.black,
      );
    }
  }

  void moveToSignup(){
    //go to sign up page
    notifyListeners();
  }
  void moveToForgottenPassword(){
    //go to forgotten password page
    notifyListeners();
  }

}`

现在这是我要发布的表单类型的注册模型或json模型

    import 'dart:convert';

import 'package:http/http.dart' as http;

class RegisterModel {
  String phoneNumber;
  String emailAddress;
  String firstName;
  String lastName;
  String password;

  RegisterModel(
      {this.phoneNumber,
        this.emailAddress,
        this.firstName,
        this.lastName,
        this.password});

  RegisterModel.fromJson(Map<String, dynamic> json) {
    phoneNumber = json['phoneNumber'];
    emailAddress = json['emailAddress'];
    firstName = json['firstName'];
    lastName = json['lastName'];
    password = json['password'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['phoneNumber'] = this.phoneNumber;
    data['emailAddress'] = this.emailAddress;
    data['firstName'] = this.firstName;
    data['lastName'] = this.lastName;
    data['password'] = this.password;
    return data;
  }
}

但出现错误

    D/skia    ( 5144): Shader compilation error
D/skia    ( 5144): ------------------------
D/skia    ( 5144): Errors:
D/skia    ( 5144): 
D/skia    ( 5144): Shader compilation error
D/skia    ( 5144): ------------------------
D/skia    ( 5144): Errors:
D/skia    ( 5144): 
D/skia    ( 5144): Shader compilation error
D/skia    ( 5144): ------------------------
D/skia    ( 5144): Errors:
D/skia    ( 5144): 
D/EGL_emulation( 5144): eglMakeCurrent: 0xec226560: ver 3 0 (tinfo 0xee67fcb0)
D/skia    ( 5144): Shader compilation error
D/skia    ( 5144): ------------------------
D/skia    ( 5144): Errors:
D/skia    ( 5144): 
E/flutter ( 5144): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: NoSuchMethodError: The getter 'text' was called on null.
E/flutter ( 5144): Receiver: null
E/flutter ( 5144): Tried calling: text
E/flutter ( 5144): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/flutter ( 5144): #1      UserOnboardingModel.createRegister (package:logistics_app/models/userOnboardingModel.dart:31:59)
E/flutter ( 5144): #2      UserOnboardingModel.passRegister (package:logistics_app/models/userOnboardingModel.dart:46:23)
E/flutter ( 5144): #3      _buildCircleAvatar.<anonymous closure>.<anonymous closure> (package:logistics_app/ui/sign_up_view.dart:241:18)
E/flutter ( 5144): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
E/flutter ( 5144): #5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
E/flutter ( 5144): #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
E/flutter ( 5144): #7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
E/flutter ( 5144): #8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
E/flutter ( 5144): #9      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:256:7)
E/flutter ( 5144): #10     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:158:27)
E/flutter ( 5144): #11     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:224:20)
E/flutter ( 5144): #12     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
E/flutter ( 5144): #13     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
E/flutter ( 5144): #14     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
E/flutter ( 5144): #15     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
E/flutter ( 5144): #16     _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 5144): #17     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 5144): #18     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 5144): #19     _invoke1 (dart:ui/hooks.dart:267:10)
E/flutter ( 5144): #20     _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
E/flutter ( 5144): 
D/skia    ( 5144): Shader compilation error
D/skia    ( 5144): ------------------------
D/skia    ( 5144): Errors:
D/skia    ( 5144): 
D/skia    ( 5144): Shader compilation error
D/skia    ( 5144): ------------------------
D/skia    ( 5144): Errors:
D/skia    ( 5144): 

所以大家在这里要做的就是尝试在createRegister()的api中发布表单注册信息。

不是我在整个代码中都使用提供程序

    import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:logistics_app/models/registerApi.dart';
import 'package:logistics_app/models/userOnboardingModel.dart';
import 'package:provider/provider.dart';
import 'package:logistics_app/ui/login_view.dart';

import '../models/userOnboardingModel.dart';
import '../models/userOnboardingModel.dart';
import '../models/userOnboardingModel.dart';
import '../models/userOnboardingModel.dart';
import '../models/userOnboardingModel.dart';
import '../models/userOnboardingModel.dart';
import '../models/userOnboardingModel.dart';


class SignUpView extends StatelessWidget{
  static const String SIGN_UP_ROUTE = "/signup";

  @override
  Widget build(BuildContext context){

    return Scaffold(
      backgroundColor: Colors.white,

      body: _buildBody(context),
    );
  }
}

Future<RegisterModel> _futureRegister;

Widget _buildBody(context){
  return SingleChildScrollView(
    child: Padding(padding: EdgeInsets.only(left: 32.0, top: 80.0,right:32.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text('Signup',
            style: TextStyle(
              fontFamily: 'PlayfairDisplay',
              fontSize: 38.0,
              fontStyle: FontStyle.normal,
              fontWeight: FontWeight.normal,
              color: Colors.black,),),
          SizedBox(height: 16.0,),
          _buildButtonRow(),
          SizedBox(height: 36.0,),
          Text('or',
            style: TextStyle(
              fontFamily: 'Gordita',
              fontWeight: FontWeight.normal,
              fontSize: 12.0,
            ),
          ),
          Consumer<UserOnboardingModel>(
            builder: (context, mValue, child) => Form(
              key: mValue.formKey,
              child: Column(
                children: [
                  SizedBox(height: 29.0,),
                  _buildNameField(),
                  SizedBox(height: 63.0,),
                  _buildEmailField(),
                  SizedBox(height: 67.0,),
                  _buildPasswordField(),
                  SizedBox(height: 69.0,),
                  _buildPhonenumber(),
                  SizedBox(height: 51.0,),
                  _buildCircleAvatar(),
                  SizedBox(height: 60.8,),
                  _buildFirstText(),
                  SizedBox(height: 12.0,),
                  _buildLoginText(context),
                  SizedBox(height: 40.0,),
                ],
              ),
            ),
          )
        ],
      ),),
  );
}

Widget _buildButtonRow(){
  return SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: <Widget>[
        FlatButton(
          child: Container(
            height: 50.0,
            width: 130.0,

            child: Center(
              child: Text('GOOGLE',
                style: TextStyle(
                  fontFamily: 'Lato',
                  fontSize: 12.0,
                  fontWeight: FontWeight.normal,),),
            ),
            decoration: BoxDecoration(
              color: Color(0xFFF5F6FA),
              borderRadius: BorderRadius.circular(5.0),
            ),
          ),
          onPressed: (){},
        ),
        FlatButton(
          child: Container(
            height: 50.0,
            width: 130.0,

            child: Center(
              child: Text('FACEBOOK',
                style: TextStyle(
                  fontFamily: 'Lato',
                  fontSize: 12.0,
                  fontWeight: FontWeight.normal,
                ),),
            ),
            decoration: BoxDecoration(
              color: Color(0xFFF5F6FA),
              borderRadius: BorderRadius.circular(5.0),
            ),
          ),
          onPressed: (){},
        ),
      ],
    ),
  );
}

Widget _buildNameField(){
  return Consumer<UserOnboardingModel>(
    builder: (context, mValue, child) => Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        Expanded(
          child: TextFormField(
            controller: mValue.firstController,
            validator: (v) => mValue.validateFirstName(v),
            obscureText: false,
            decoration: InputDecoration(
              hintText: 'First Name',
              hintStyle: TextStyle(
                fontFamily: 'Lato',
                fontSize: 14.0,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
        ),
        SizedBox(width: 10.0,),
        Expanded(
          child: TextFormField(
            controller: mValue.lastController,
            validator: (v) => mValue.validateLastName(v),
            obscureText: false,
            decoration: InputDecoration(
              hintText: 'Last Name',
              hintStyle: TextStyle(
                fontFamily: 'Lato',
                fontSize: 14.0,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
        ),
      ],
    ),
  );
}

Widget _buildEmailField(){
  return Consumer<UserOnboardingModel>(
    builder: (context, mValue, child) => TextFormField(
      controller: mValue.emailController,
      validator: (v) => mValue.validateEmail(v),
      keyboardType: TextInputType.emailAddress,
      decoration: InputDecoration(
        hintText: 'Email address',
        hintStyle: TextStyle(
          fontFamily: 'Lato',
          fontSize: 14.0,
          fontWeight: FontWeight.w500,
        ),
      ),
    ),
  );
}

Widget _buildPasswordField(){
  return Consumer<UserOnboardingModel>(
    builder: (context, mValue, child) => TextFormField(
      validator: (v) => mValue.validatePassword(v),
      controller: mValue.passwordController,
      obscureText: mValue.showPassword,
      decoration: InputDecoration(
        hintText: 'Password',
        hintStyle: TextStyle(
          fontFamily: 'Lato',
          fontSize: 14.0,
          fontWeight: FontWeight.w500,
        ),
        suffix: InkWell(
          onTap: mValue.togglePassword,
          child: Text(mValue.showPassword ? "show" : "hide", style: TextStyle(color: Colors.black),),
        ),

      ),

    ),
  );
}

Widget _buildPhonenumber(){
  return Consumer<UserOnboardingModel>(
    builder: (context, mValue, child) => TextFormField(
      validator: (v) => mValue.validatePhoneNumber(v),
      controller: mValue.phoneController,
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
        hintText: 'Phone Number',
        hintStyle: TextStyle(
          fontFamily: 'Lato',
          fontSize: 14.0,
          fontWeight: FontWeight.w500,
        ),
      ),
    ),
  );
}

Widget _buildCircleAvatar(){
  return Consumer<UserOnboardingModel>(
    builder: (context, mValue, child) => InkWell(
        onTap: (){
          mValue.validateForm();
          mValue.passRegister();
          mValue.moveToLogin(context);
        },
        child: CircleAvatar(
          radius: 28.93,
          backgroundColor: Colors.black,
          foregroundColor: Colors.white,
          child: Icon(Icons.arrow_forward),
        ),
      ),
  );
}

Text _buildFirstText(){
  return Text('Already have an account?',
    style: TextStyle(
      fontFamily: 'Lato',
      fontSize: 14.0,
      fontWeight: FontWeight.normal,
    ),);
}
Widget _buildLoginText(context){
  return Consumer<UserOnboardingModel>(
    builder: (context, value, child) => InkWell(
      child: Row(
        children: <Widget>[
          Text('LOGIN',
            style: TextStyle(
              fontFamily: 'Lato',
              fontSize: 14.0, fontWeight:
            FontWeight.bold,),),

          Icon(Icons.arrow_right)
        ],
      ),
      onTap: (){
        Navigator.pushNamed(context, LogIn.LOG_IN_ROUTE);
      },
    ),
  );
}

1 个答案:

答案 0 :(得分:0)

查看您的代码,您尚未创建controller的实例,只为它们声明了变量:

尝试以下代码:

class UserOnboardingModel extends ChangeNotifier with ValidationMixin{

  TextEditingController firstController = TextEditingController(); // create your controllers 
  TextEditingController lastController = TextEditingController();
  TextEditingController passwordController = TextEditingController();
  TextEditingController emailController = TextEditingController();
  TextEditingController phoneController = TextEditingController();
  bool showPassword = true;

  final formKey = GlobalKey<FormState>();

  Future<RegisterModel> _futureRegister;

  Future<RegisterModel> createRegister()async{
    final http.Response response = await http.post(
        "apiKey",
        body: jsonEncode(<String, String>{
          'firstName' : validateFirstName(firstController.text), // access the controllers here
          'lastName' : validateLastName(lastController.text),
          'emailAddress' : validateEmail(emailController.text),
          'phoneNumber' : validatePhoneNumber(phoneController.text),
          'password' : validatePassword(passwordController.text)
        })
    );
    if(response.statusCode == 201){
      return RegisterModel.fromJson(json.decode(response.body));
    }else{
      throw Exception('Failed to create Register');
    }
  }

... // the rest of your code