Как преобразовать ответ API в объект класса

#flutter #dart

#flutter #dart

Вопрос:

У меня есть класс SuperHero и одно потребление API, которое возвращает ответ со значениями, которые я хочу создать нового супергероя, но я немного не понимаю, как это сделать.

Это мой класс:

 import 'dart:convert';

SuperHero superHeroFromJson(String str) => SuperHero.fromJson(json.decode(str));

String superHeroToJson(SuperHero data) => json.encode(data.toJson());

class SuperHero {
    SuperHero({
        this.name,
        this.mainPower,
        this.worstEnemy,
    });

    String name;
    String mainPower;
    String worstEnemy;

    factory SuperHero.fromJson(Map<String, dynamic> json) => SuperHero(
        name: json["name"],
        mainPower: json["mainPower"],
        worstEnemy: json["worstEnemy"],
    );

    Map<String, dynamic> toJson() => {
        "name": name,
        "mainPower": mainPower,
        "worstEnemy": worstEnemy,
    };
}
 

SuperHeroController

 class SuperHeroController {
  final String hero;

  SuperHeroController({this.hero}){
    loadData(hero);
  }

  Future<Map<String, dynamic>> loadData(String usuario) async {
    final String url = ****;

    final Map<String, dynamic> queryParams = {
      'hero': hero,
    };

    var uri = Uri.parse(url).resolveUri(Uri(queryParameters: queryParams));

    final response = await http.get(
      uri,
      headers: {"Content-Type": "application/json"},
    );

    var data = json.decode(response.body);

    print(data);
  }
}
 

Мой виджет

 SuperHero hero;
  SuperHeroController _superHeroController;

  HeroWidget(hero){
    hero = hero;
  }

  @override
  void initState() {
    super.initState();
    _heroController = SuperHeroController (hero: Provider.of<Auth>(context, listen: false).id); // getting the user's hero id
  }
 

При запуске этого кода вызывается initState, он показывает в консоли структуру, которую я должен построить в классе SuperHero, но я не знаю, как это сделать. Где я запускаю метод SuperHeroFromJson в возврате и получаю объект SuperHero с ответом?

Ответ №1:

Что-то вроде:

 @override
void initState() {
  super.initState();
  _heroController = SuperHeroController(hero: Provider.of<Auth>(context, listen: false).id);
  _loadHero();
}

_loadHero() async {
    hero = await _heroController.loadData();
}
 

и контроллер…

 class SuperHeroController {
  final String hero;

  SuperHeroController({this.hero});

  Future<SuperHero> loadData() async {
    ...
    var data = json.decode(response.body);
    return SuperHero.fromJson(data);
  }
}
 

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

1. Если я вызываю hero.name в вашем loadHero он показывает имя, но если я попытаюсь написать это имя другим способом, чтобы показать на экране, он выдает: The getter name was called on null

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

3. вы пробовали setState() ?

4. Пожалуйста, обратите внимание, что loadHero() это async функция. Скорее hero всего, он не загружается при попытке обновить его имя. Убедитесь, что вы получаете доступ hero только после его загрузки.