Septian Dika
Septian Dika

Reputation: 596

How to Create Model for Nested JSON where There is a List of JSON Inside Nested JSON?

I have a structure of JSON response like code below (example):

{
  "data": {
    "items": [
      {
        "id": 1,
        "name": "Baburiki",
        "jutsu_variant": [
          {
            "jutsu_name": "wind release",
            "damage": 1200,
          },
        ], 
      },
      {
        "id": 2,
        "name": "Zee",
        "jutsu_variant": [
          {
            "jutsu_name": "wind release",
            "damage": 1200,
          },
          {
            "jutsu_name": "kage bunshin",
            "damage": 2000,
          },
        ], 
      },
    ],
  },
}

There is a list of JSON on the items key and in that key, there is another list of JSON on the jutsu_variant key.

I have created a class model to store the JSON response like the following code

class ShinobiData {
  int? id;
  String? shinobiName;
  JutsuVariant? jutsuVariant;

  ShinobiData({
    this.id,
    this.shinobiName,
    this.jutsuVariant,
  });

  factory ShinobiData.fromJson(Map<String, dynamic> json) {
    return ShinobiData(
      id: json['id'],
      shinobiName: json['name'],
      jutsuVariant: json['jutsu_variant'],
    );
  }
}

class JutsuVariant {
  String? jutsuName;
  int? jutsuDamage;

  JutsuVariant({this.jutsuName, this.jutsuDamage});

  factory JutsuVariant.fromJson(Map<String, dynamic> json) {
    return JutsuVariant(
      jutsuName: json['jutsu_name'],
      jutsuDamage: json['damage'],
    );
  }
}

The model is working fine if there is no list on the jutsu_variant key.

This is my class for getting the API response of POST requests. (created with provider state management)

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:learning_api/model/shinobi_model.dart';

class CatalogResponse with ChangeNotifier {
  Map<String, dynamic> _map = {};
  bool _error = false;
  String _errorMessage = '';
  List<ShinobiData> _shinobis = [];

  Map<String, dynamic> get map => _map;

  List<ShinobiData> get shinobis => _shinobis;

  bool get error => _error;

  String get errorMessage => _errorMessage;

  Future<void> get fetchData async {
    var _finalBody = {
      'page': 1,
      'items_per_page': 5,
    };

    String _body = const JsonEncoder().convert(_finalBody);

    final response = await http.post(
      Uri.parse('https://***/url'),
      body: _body,
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
    );

    if (response.statusCode == 200) {
      try {
        _map = (jsonDecode(response.body))['data'];
        List<dynamic> _listShinobi = (_map)['items'];

        // this loop will add each item in the items key 
        for (int i = 0; i < _listShinobi.length; i++)
          _shinobis.add(CatalogData.fromJson(_listItem[i]));

        _error = false;
      } catch (e) {
        _error = true;
        _errorMessage = e.toString();
        _map = {};
        _catalogs = [];
      }
    } else {
      _error = true;
      _errorMessage = "Error: It would be your internet connection";
      _map = {};
      _catalogs = [];
    }
    notifyListeners();
  }

  void initialValues() {
    _map = {};
    _catalogs = [];
    _error = false;
    _errorMessage = "";
    notifyListeners();
  }
}

The above code works perfectly for name and id key calling. But the problem occurs when calling the jutsu_variant key. What should I do to be able to call the value of the jutsu_name and the damage key that is in the jutsu_variant key?

Cases like this do not exist in any tutorial resources. Maybe your answer will be very valuable in the future. Thank you in advance

Upvotes: 0

Views: 159

Answers (2)

Wai Han Ko
Wai Han Ko

Reputation: 1043

This IDE plugin JosnToDart is very convenience for me. It can generate response model just paste json to this. More we can choose nullable or not option when generate.

Upvotes: 0

Xoltawn
Xoltawn

Reputation: 1875

in your ShinobiData class you should use List<JutsuVariant> instead of JutsuVariant

you can use json_serializable or even freezed to generate these files automatically for you

Upvotes: 1

Related Questions