Как я могу вызвать данные из класса модели, которые в модели списка флаттер

Я пытаюсь получить данные из своей модели, но я не получаю данные в текстовом виджете. После получения данных из JSON я использую модель для сохранения данных. Я могу распечатать данные после вызова API в функции, но не когда я пытался получить данные из модели внутри виджета. Я использую provider, но получаю нулевое значение от модели. Я не понимаю, как именно выполнить эту задачу, следуя моему объекту JSON.

{
"statusCode": 200,
"success": true,
"messages": [],
"data": [
 
    {
        "id": 36,
        "title": "Muhurtam",
        "filename": "Muhurtam.jpg",
        "mimetype": "image/jpeg",
        "directcalling": 1,
        "parentid": null,
        "subcat": [
            {
                "id": 50,
                "title": "abc",
                "filename": "abc.png",
                "mimetype": "image/png",
                "directcalling": 0,
                "parentid": 36,
                "subcat": []
            }
        ]

Я создал класс модели для приведенного выше json, ниже моя модель

Модель

    import 'package:flutter/material.dart';

class Categories with ChangeNotifier {
  Categories({
    this.statusCode,
    this.success,
    this.messages,
    this.data,
  });
  late final int? statusCode;
  late final bool? success;
  late final List<dynamic>? messages;
  late final List<Data>? data;

  Categories.fromJson(Map<String, dynamic> json) {
    statusCode = json['statusCode'];
    success = json['success'];
    messages = List.castFrom<dynamic, dynamic>(json['messages']);
    data = List.from(json['data']).map((e) => Data.fromJson(e)).toList();
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    _data['statusCode'] = statusCode;
    _data['success'] = success;
    _data['messages'] = messages;
    _data['data'] = data!.map((e) => e.toJson()).toList();
    return _data;
  }

  List get items {
    // if (_showFavoritesOnly) {
    //   return _items.where((prodItem) => prodItem.isFavorite).toList();
    // }
    return [...data!];
  }
}

class Data extends ChangeNotifier {
  Data({
    this.id,
    this.title,
    this.filename,
    this.mimetype,
    this.directcalling,
    this.parentid,
    this.subcat,
  });
  late final int? id;
  late final String? title;
  late final String? filename;
  late final String? mimetype;
  late final int? directcalling;
  late final Null parentid;
  late final List<Subcat>? subcat;

  Data.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    title = json['title'];
    filename = json['filename'];
    mimetype = json['mimetype'];
    directcalling = json['directcalling'];
    parentid = null;
    subcat = List.from(json['subcat']).map((e) => Subcat.fromJson(e)).toList();
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    // _data['id'] = id;
    _data['title'] = title;
    _data['filename'] = filename;
    // _data['mimetype'] = mimetype;
    _data['directcalling'] = directcalling;
    // _data['parentid'] = parentid;
    // _data['subcat'] = subcat.map((e) => e.toJson()).toList();
    return _data;
  }
}

class Subcat {
  Subcat({
    required this.id,
    required this.title,
    required this.filename,
    required this.mimetype,
    required this.directcalling,
    required this.parentid,
    required this.subcat,
  });
  late final int id;
  late final String title;
  late final String filename;
  late final String mimetype;
  late final int directcalling;
  late final int parentid;
  late final List<dynamic> subcat;

  Subcat.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    title = json['title'];
    filename = json['filename'];
    mimetype = json['mimetype'];
    directcalling = json['directcalling'];
    parentid = json['parentid'];
    subcat = List.castFrom<dynamic, dynamic>(json['subcat']);
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    //_data['id'] = id;
    _data['title'] = title;
    _data['filename'] = filename;
    //_data['mimetype'] = mimetype;
    _data['directcalling'] = directcalling;
    //_data['parentid'] = parentid;
    //_data['subcat'] = subcat;
    return _data;
  }
}

Ниже приведен мой виджет, в котором я хочу проверить данные внутри моей модели. Я не понимаю, как именно вызывать данные, которые находятся внутри модели.

Widget build(BuildContext context) {
    var image = Provider.of<FlutterFunctions>(context, listen: false);
   var cat = Provider.of<Category>(context, listen: false).categories;
    return Scaffold(
      appBar: AppBar(),
      drawer: const AppDrawer(),
      body:  Text("${cat?.data == null ? "there is no data" : cat!.statusCode}")

Преобразование API

     class Category with ChangeNotifier {
  Categories? categories;
  Future<void> getCatogories(BuildContext cont) async {
    final url = PurohitApi().baseUrl + PurohitApi().getcategory;

    try {
      final client = RetryClient(
        http.Client(),
        retries: 4,
        when: (response) {
          return response.statusCode == 401 ? true : false;
        },
        onRetry: (req, res, retryCount) async {
          //print('retry started $token');

          if (retryCount == 0 && res?.statusCode == 401) {
            var accessToken = await Provider.of<Auth>(cont, listen: false)
                .restoreAccessToken();
            // Only this block can run (once) until done

            req.headers['Authorization'] = accessToken;
          }
        },
      );
      var response = await client.get(
        Uri.parse(url),
        headers: {
          'Content-Type': 'application/json; charset=UTF-8',
        },
      );
      Map<String, dynamic> categoryTypes = json.decode(response.body);

      categories = Categories.fromJson(categoryTypes);
      notifyListeners();
    } catch (e) {
      print(e);
    }
  }
}

Вы можете использовать один из этих сайтов для анализа вашего кода json в Dart: javiercbk.github.io/json_to_dart или app.quicktype.io. Или вы можете использовать расширение Visual Studio Code под названием Json to Dart Model для той же цели.

Ante Bule 01.12.2022 09:57

да, я уже преобразовал его, но я хочу использовать преобразованные данные внутри виджетов

Santosh Kumar 01.12.2022 10:17

Если вы сделали преобразование модели правильно, то я подозреваю ту часть, где вы это называете. Можете ли вы обновить свой вопрос с помощью кода, в котором вы вызываете преобразование из json (после ответа API).

Ante Bule 01.12.2022 10:23

обновление с преобразованием. Я Абель для печати данных из функции, в которой я вызываю API, но не получаю данные внутри виджетов.

Santosh Kumar 01.12.2022 10:32

Вы нигде не назначаете конвертированные категории. Должно быть что-то вроде: yourCategoriesInProvider = Categories.fromJson(categoryTypes);

Ante Bule 01.12.2022 10:50

Я обновил вопрос, который пробовал, как вы сказали, но не работал

Santosh Kumar 01.12.2022 11:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы используете Provider неправильно. Ваши модели, такие как Categories, Data и т. д., не должны расширять ChangeNotifier. Вы должны создать класс Provider, который использует ChangeNotifier, который будет иметь данные вашей модели и предоставить их где-нибудь, чтобы использовать их с Provider.of<ProviderName>(context, listen: false). Что-то вроде этого:

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (ctx) => CategoriesProvider(),
      child: MaterialApp(
        home: Sample(),
      ),
    );
  }
}

class CategoriesProvider with ChangeNotifier {
  Categories? categories;

  Future<void> getCatogories() async {
    Map<String, dynamic> categoryTypes = {
      "statusCode": 200,
      "success": true,
      "messages": [],
      "data": [
        {
          "id": 36,
          "title": "Muhurtam",
          "filename": "Muhurtam.jpg",
          "mimetype": "image/jpeg",
          "directcalling": 1,
          "parentid": null,
          "subcat": [
            {
              "id": 50,
              "title": "abc",
              "filename": "abc.png",
              "mimetype": "image/png",
              "directcalling": 0,
              "parentid": 36,
              "subcat": []
            }
          ]
        }
      ]
    };
    categories = Categories.fromJson(categoryTypes);

    notifyListeners();
  }
}

class Sample extends StatefulWidget {
  const Sample({Key? key}) : super(key: key);
  @override
  State<Sample> createState() => _SampleState();
}

class _SampleState extends State<Sample> {

  @override
  void initState() {
    Provider.of<CategoriesProvider>(context, listen: false).getCatogories();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var cat = Provider.of<CategoriesProvider>(context, listen: false).categories;
    
    return Scaffold(
      appBar: AppBar(),
      drawer: const Drawer(),
      body: Text("${cat?.data == null ? "there is no data" : cat!.statusCode}"),
    );
  }
}

Я обновил вопрос, как вы сказали, я использовал свою модель в переменной, затем я назначаю свое преобразование модели и пытался вызвать данные, используя следующий код, но я не получил никаких данных cat.categories!.statusCode

Santosh Kumar 01.12.2022 11:24

Следуйте моему ответу и создайте свой Provider, как я сделал с CategoriesProvider. Предоставьте его вашему дереву виджетов с помощью ChangeNotifierProvider( create: (ctx) => CategoriesProvider(), child: MaterialApp( home: Sample(), ), и используйте его, как я сделал с var cat = Provider.of<CategoriesProvider>(context, listen: false).categories;, чтобы получить ваши категории в переменной и использовать ее дальше в дереве виджетов.

Ante Bule 01.12.2022 11:30

Я отредактировал свой вопрос, и код попробовал то, что вы сказали, создав провайдера, как вы сказали, в классе категории, вы можете проверить мой код преобразования API в вопросе, и я вызываю категории из преобразования API в моем виджете, но он не работает

Santosh Kumar 01.12.2022 12:49

Есть ошибки? Я не знаю, в чем сейчас ваша проблема, но мой ответ работает отлично, вы можете проверить его и увидеть, а затем настроить под свои нужды.

Ante Bule 01.12.2022 13:53

хм, в вашем коде есть проблема, но я не понимаю, почему он не работает

Santosh Kumar 01.12.2022 14:30

это сработало, спасибо, я только что удалил уведомление об изменении из модели

Santosh Kumar 01.12.2022 15:01

Да, как я сказал в ответ. Рад, что это сработало, удачного кодирования 😉

Ante Bule 01.12.2022 15:03

Другие вопросы по теме