отправьте запрос http: получатель 'длина' был вызван при нулевом флаттере - PullRequest
1 голос
/ 20 сентября 2019

Я хочу создать пользователя, когда я вызываю мой API.Я создал Future с помощью URL, и я назвал свою модель на странице экрана.Я получаю все данные в своей форме, но когда я вызываю свой API, у меня появляется эта ошибка:

Получатель 'длина' вызван на нуль ...

Модель пользователя:

class Candidate {
  int id;
  String firstname;
  String lastname;
  String email;

  Candidate({this.id, this.firstname, this.lastname, this.email});

  factory Candidate.fromJson(Map<String, dynamic> json) {
    return Candidate(
      id: json['id'],
      firstname: json['firstname'],
      lastname: json['lastname'],
      email: json['email'],
    );
  }

  Map toMap() {
    var map = new Map<String, dynamic>();
    map["id"] = id;
    map["firstname"] = firstname;
    map["lastname"] = lastname;
    map["email"] = email;
    return map;
  }

  Future<Candidate> candidateAuth({Map body}) async {
    String url = 'http://10.0.2.2:3000/v1/api/auth/candidate';
    final response = await http.post(url, body: body, headers: {"Accept": "application/json"});

    if (response.statusCode == 201) {
      return Candidate.fromJson(json.decode(response.body));
    } else {
      throw Exception('Failed auth');
    }
  }
}

РЕДАКТИРОВАТЬ:

Я добавил весь код страницы входа с модификацией.

На странице входа в систему:

import 'package:blackbox/models/candidate_model.dart';
import 'package:blackbox/screens/theme_page.dart' as t;
import 'package:flutter/material.dart';

class Login extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _Login();
  }
}

class _Login extends State<Login> {
  final _formKey = GlobalKey<FormState>();
  String email, lastname, firstname;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        leading: Image.asset(
          'assets/img/logo_ineat.png',
          fit: BoxFit.contain,
          height: 32,
        ),
        title: Text('BlackBox'),
      ),
      body: new Center(
        child: new SingleChildScrollView(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              new Container(
                margin: EdgeInsets.only(top: 10.0, bottom: 20.0),
                alignment: Alignment.topCenter,
                child: new Text('Se Connecter',
                    style: new TextStyle(
                        fontSize: 24, fontWeight: FontWeight.bold)),
              ),
              new Card(
                elevation: 10,
                color: Colors.pink,
                child: new Container(
                  width: MediaQuery.of(context).size.width / 2,
                  height: MediaQuery.of(context).size.height / 3,
                  child: new Image.asset('assets/img/logo_ineat.png',
                      fit: BoxFit.contain),
                ),
              ),
              new Form(
                key: _formKey,
                child: new Column(
                  children: <Widget>[
                    new Row(
                      children: <Widget>[
                        new Container(
                          width: MediaQuery.of(context).size.width / 5,
                          margin:
                              EdgeInsets.only(left: 10, top: 5, right: 10.0),
                          child: new Text("Nom : "),
                        ),
                        new Container(
                          width: MediaQuery.of(context).size.width / 1.4,
                          margin: EdgeInsets.only(top: 5, right: 10.0),
                          child: new TextFormField(
                            keyboardType: TextInputType.text,
                            decoration: new InputDecoration(
                                labelText: 'Entrez votre nom'),
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Veuillez remplir le champ nom';
                              }
                              lastname = value;
                              return null;
                            },
                          ),
                        ),
                      ],
                    ),
                    new Row(
                      children: <Widget>[
                        new Container(
                          width: MediaQuery.of(context).size.width / 5,
                          margin:
                              EdgeInsets.only(left: 10, top: 5, right: 10.0),
                          child: new Text("Prénom : "),
                        ),
                        new Container(
                          width: MediaQuery.of(context).size.width / 1.4,
                          margin: EdgeInsets.only(top: 5, right: 10.0),
                          child: new TextFormField(
                            keyboardType: TextInputType.text,
                            decoration: new InputDecoration(
                                labelText: 'Entrez votre prénom'),
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Veuillez remplir le champ prénom';
                              }
                              firstname = value;
                              return null;
                            },
                          ),
                        ),
                      ],
                    ),
                    new Row(
                      children: <Widget>[
                        new Container(
                          width: MediaQuery.of(context).size.width / 5,
                          margin:
                              EdgeInsets.only(left: 10, top: 5, right: 10.0),
                          child: new Text("Email : "),
                        ),
                        new Container(
                          width: MediaQuery.of(context).size.width / 1.4,
                          margin: EdgeInsets.only(top: 5, right: 10.0),
                          child: new TextFormField(
                            keyboardType: TextInputType.emailAddress,
                            decoration: new InputDecoration(
                                labelText: 'Entrez votre email'),
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Veuillez remplir le champ email';
                              }
                              email = value.toLowerCase();
                              return null;
                            },
                          ),
                        ),
                      ],
                    ),
                    new Container(
                      margin: EdgeInsets.only(top: 30, bottom: 5, right: 10.0),
                      alignment: Alignment.bottomRight,
                      child: new RaisedButton.icon(
                          onPressed: () {
                            setState(() async {
                              if (_formKey.currentState.validate()) {
                                Candidate newPost = new Candidate(
                                  lastname: lastname,
                                  firstname: firstname,
                                  email: email,
                                );
                                var candidate = await Candidate()
                                    .candidateAuth(body: newPost.toMap());
                              }
                            });
                          },
                          icon: Icon(Icons.check),
                          label: Text('Valider')),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Сообщение об ошибке:

Произошло исключение.
NoSuchMethodError (NoSuchMethodError: Вызывался получатель «length»on null Receiver: null Пробный вызов: length) При обработке жеста было выдано следующее утверждение: аргумент обратного вызова setState () возвратил Future.Метод setState () в _Login # e2125 был вызван с замыканием или методом, который вернул Future.Может быть, это помечено как «асинхронный».Вместо выполнения асинхронной работы внутри вызова setState () сначала выполните эту работу (без обновления состояния виджета), а затем синхронно обновите состояние внутри вызова setState ()

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

Было:

headers: {'Content-type': 'application/json','Accept': 'application/json'}
0 голосов
/ 20 сентября 2019

Поскольку candidateAuth возвращает Future, вам необходимо добавить await:

Candidate newPost = new Candidate(
  lastname: lastname,
  firstname: firstname,
  email: email,
);
var candidate = await Candidate().candidateAuth(body: newPost.toMap());

UPD:

В соответствии с сообщением об ошибке удалить async из setState:

onPressed: () async {
  if (_formKey.currentState.validate()) {
    Candidate newPost = new Candidate(
        lastname: lastname,
        firstname: firstname,
        email: email,);
    var candidate = await Candidate().candidateAuth(body: newPost.toMap());

    setState(() {
      // do what you need with candidate here
    });
  }   
},
...