Flutter Sql FutureBuilder снимок null - PullRequest
0 голосов
/ 08 апреля 2020

еще раз. Фьючерсы кажутся постоянным источником путаницы для меня.

Я пытаюсь использовать FutureBuilder на странице, но snapshot.data всегда имеет значение null, даже если я могу напечатать данные из DBprovider прямо перед его возвратом.

У меня есть класс CentreDetailScreen, который использует initState для создания будущего.

class _CentreDetailScreenState extends State<CentreDetailScreen> {
  Future centreFuture;

  @override
  void initState() {
    super.initState();
    centreFuture = widget._centresBloc.getCentre(widget.centreReference);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
          future: centreFuture,
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return CircularProgressIndicator();
              case ConnectionState.active:
              case ConnectionState.waiting:
                return CircularProgressIndicator();
              case ConnectionState.done:
                print('snapshot: ${snapshot.data}'); <-always null
                return Container(...//build UI

В CentresBlo c У меня есть:

  Future<ClimbingCentre> getCentre(String centreId) async {
    print('BloC get Centre');  <-- this prints
    var _centre = await ClimbDB.db.getCentre(centreId);
    print('Bloc has got a centre $_centre') <-- this doesn't
    return _centre;
  }

, а затем DBprovider ClimbDB имеет:

Future<ClimbingCentre> getCentre(String centreId) async {
    try {
      var map = Map<String, dynamic>();
      map['action'] = _GET_ONE_ACTION;
      map['centreId'] = centreId;
      final response = await http.post(
          'http://xxx.xxx.xx.x/flutter/climbinside/centre.php',
          body: map);
      if (200 == response.statusCode) {
        var centre = json.decode(response.body);
        var toReturn =
            centre.map((centre) => new ClimbingCentre.fromJson(centre));
         print($toReturn); <-prints 'instance of ClimbingCentre'
        return toReturn;
      } else {
        throw Exception('we were not able to download json data');
      }
    } catch (e) {
      throw Exception('Get centre: unable to download JSON');
    }
  }

Я перепробовал много разных вещей ... иногда я получаю ошибки о том, что Future не является подтипом Future ... другие вызывают исключение 'Unable Download JSON' ... Я не могу понять все это.

Буду очень признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

решено:

Сработало после переписывания метода from Json в классе модели для ClimbingCentre. Первоначально я следовал структуре из flutter.dev , например:

  ClimbingCentre.fromJson(Map<String, dynamic> json) {
      centreId: json['CentreId'],
      name: json['Name'],
      imagePath: json['ImagePath'],
  }

Но я изменил ее на эту, которую я использовал в другом классе:

  factory ClimbingCentre.fromJson(Map<String, dynamic> jsonData) {
    ClimbingCentre c = ClimbingCentre(
      centreId: jsonData['CentreId'],
      name: jsonData['Name'],
      imagePath: jsonData['ImagePath'],
    );
    return c;
  }
0 голосов
/ 08 апреля 2020

Вы должны всегда проверять, если snapshot не имеет error.

В вашем случае вы получаете ошибку, потому что вы определили свои переменные, используя var, это сложно и подвержено ошибкам потому что вы не получите полную помощь компилятора, чтобы сообщить вам, что ваш код сломается во время выполнения. Всегда старайтесь использовать полностью типизированную переменную, чтобы избежать этой ошибки, поэтому избегайте также dynamic.

Вы должны вернуть переменную того же типа T из Future<T> в свой класс репозитория.

Кроме того, постарайтесь не отбрасывать переменную Exception, передавать ее какому-либо новому объекту Exception (добавить ее к String или, в идеале, передавать конструктору в качестве внутреннего исключения), она содержит полезную информацию отладить ваш код.

...