Будущий конструктор возвращает нулевые данные из API, даже если снимок не является нулевым

#flutter #mobile #flutter-futurebuilder

Вопрос:

Я получаю нулевые значения ListView.builder внутри FutureBuilder вызова API, когда я распечатываю тело ответа, оно не пустое, и когда я распечатываю snapshot.hasData его, оно возвращается true . Когда я жестко кодирую значения для возвращаемого объекта (пользователя) из вызова API, он возвращает это жестко закодированное значение. Вот код: вызов API:

 Future<User> getUser() async {
    final response = await apiRequest(
        Method.GET, '/user/ID');
    Map<String, dynamic> jsonDecodedResponse = jsonDecode(response.body);
    return User(
      id: jsonDecodedResponse['id'],
      dob: jsonDecodedResponse['dob'], // when I hardcode this to dob: 'QWERTY' it returns the value QWERTY to the FutureBuilder
    );
  }
 

Список пользователей с будущим строителем, где я вызываю api getUser() :

  Future<User> _getUserList() async {
   
    var _userData = await APICalls.instance.getUser();

    return _userData;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder<User>(
          future: _getUserList(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
print(snapshot.hasData); // returns true
              return ListView.builder(
                itemCount: 2, //snapshot.data.length is not working so I had to set it to count 2
                itemBuilder: (context, index) {
                return Text("${snapshot.data.dob}"); // this is null unless I hard code it in the API call return statement
                       }
                  );
                },
              );
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return Container();
          },
        ),
      ),
    );
  }
}
 

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

 class Userextends ChangeNotifier {
  final String id,dob;

  User(
      {this.id,
      this.dob});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      dob: json['dob'],
    
    );
  }
}

 

Любая помощь приветствуется, заранее спасибо!

Комментарии:

1. Я бы поставил точку останова в Map<String, dynamic> jsonDecodedResponse = jsonDecode(response.body); и осмотрел тело, а затем взглянул на объект jsonDecodedResponse

Ответ №1:

Вы используете FutureBuilder<VehicleData> , но хотите получить доступ FutureBuilder<User>

Измените его на <User>

Комментарии:

1. опечатка, изменит ее в исходном сообщении.

2. пожалуйста, опубликуйте свой файл json.

3. Пока я копировал/вставлял файл json, я понял ошибку и опубликовал его в качестве ответа. Еще раз спасибо, приятель!

4. Пока я вас беспокою, может быть, вы знаете, почему я получаю и ошибаюсь Error: The getter 'length' isn't defined for the class 'User'. , когда использую snapshot.data.length itemCount: snapshot.data.length в этом же модуле? Должен ли я определить модель в виде списка, а затем использовать snapshot.data.length ?

5. Вообще не беспокойтесь, потому что пользователь не является списком или повторяющимся объектом. Если у вас есть список пользователей, вы можете зафиксировать их длину

Ответ №2:

Хорошо, поэтому я должен был добавить ['data'] в конце Map<String, dynamic> jsonDecodedResponse = jsonDecode(response.body); , чтобы окончательное решение этой «проблемы» было

 Map<String, dynamic> jsonDecodedResponse = jsonDecode(response.body)['data'];
 

Следовало бы уделить больше внимания JsonResponse!

Спасибо всем вам за помощь.