Home > Software design >  How To access data in a list but inside the list has nested maps
How To access data in a list but inside the list has nested maps

Time:10-30

Hello Im trying to get data from the Jasonplaceholder Api, and I want to map it in a dart model but I tried videos on YouTube and none of them work and I use autogenerated models but the data that received are inside a list but in that list have nested maps

  var myMap=[{
    "name" : "Ravindu",
    "age" : 20,
    "scl" : "smc",
    "address" :
      {
        "city" : "Kegalle",
        "country" : "sri lanka"
      }
  },
            {
    "name" : "Ravindu1",
    "age" : 20,
    "scl" : "smc1",
    "address" :
      {
        "city" : "Kegalle1",
        "country" : "sri lanka1"
      }
  }];
  

like this I want this to map to a Molde class and also, I want to know how to access Items inside this map tried myMap[0]["address"] but it only retrieve the whole map of address in the 0 index

so How can I pass these type of Json data to a model class

this is the actual url im working with

'''final String url ="https://jsonplaceholder.typicode.com/users"'''

I get this error when I try this on darpad

Uncaught Error: TypeError: Instance of 'JsLinkedHashMap<String, String>': type 'JsLinkedHashMap<String, String>' is not a subtype of type 'List'

this is the code I tried on dartpad

void main() {
  var myMap=[{
    "name" : "Ravindu",
    "age" : 20,
    "scl" : "smc",
    "address" :
      {
        "city" : "Kegalle",
        "country" : "sri lanka"
      }
  },
            {
    "name" : "Ravindu1",
    "age" : 20,
    "scl" : "smc1",
    "address" :
      {
        "city" : "Kegalle1",
        "country" : "sri lanka1"
      }
  }];
  
  print(myMap[0]);
  
  var addressList = myMap[0]["address"]["city"];
  print(addressList);
  
  (addressList as List).forEach((i){
    print(i["country"]);
  });
  
  
  

}

CodePudding user response:

The addressList will get from myMap[0]["address"] which will be another map. On Map, forEach callback provide key and value .forEach((key, value) {

void main() {
  List<Map<String, dynamic>> myMap = [
    {
      "name": "Ravindu",
      "age": 20,
      "scl": "smc",
      "address": {"city": "Kegalle", "country": "sri lanka"}
    },
    {
      "name": "Ravindu1",
      "age": 20,
      "scl": "smc1",
      "address": {"city": "Kegalle1", "country": "sri lanka1"}
    }
  ];

  print(myMap[0].toString());

  final addressList = myMap[0]["address"]["city"];
  print(addressList.toString()); // kegalle

  final Map<String, String> address = myMap[0]["address"];

  address.forEach((key, value) {
    print(" $key $value");
  });
}

I am also using Dart class generator extion

class Person {
  final String? name;
  final int? age;
  final String? scl;
  final Address? address;
  Person({
    this.name,
    this.age,
    this.scl,
    this.address,
  });

  Map<String, dynamic> toMap() {
    final result = <String, dynamic>{};
  
    if(name != null){
      result.addAll({'name': name});
    }
    if(age != null){
      result.addAll({'age': age});
    }
    if(scl != null){
      result.addAll({'scl': scl});
    }
    if(address != null){
      result.addAll({'address': address!.toMap()});
    }
  
    return result;
  }

  factory Person.fromMap(Map<String, dynamic> map) {
    return Person(
      name: map['name'],
      age: map['age']?.toInt(),
      scl: map['scl'],
      address: map['address'] != null ? Address.fromMap(map['address']) : null,
    );
  }

  String toJson() => json.encode(toMap());

  factory Person.fromJson(String source) => Person.fromMap(json.decode(source));
}

class Address {
  final String? city;
  final String? country;
  Address({
    this.city,
    this.country,
  });

  Map<String, dynamic> toMap() {
    final result = <String, dynamic>{};
  
    if(city != null){
      result.addAll({'city': city});
    }
    if(country != null){
      result.addAll({'country': country});
    }
  
    return result;
  }

  factory Address.fromMap(Map<String, dynamic> map) {
    return Address(
      city: map['city'],
      country: map['country'],
    );
  }

  String toJson() => json.encode(toMap());

  factory Address.fromJson(String source) => Address.fromMap(json.decode(source));
}

try to get the json structure with this model.

CodePudding user response:

First of all be sure to have json_annotation and http as a normal dependency, and json_serializable, build_runner as a dev dependencies.

Example of pubspec.yaml:

dependencies:
  json_annotation: ^4.7.0
  # used for HTTP calls
  http: ^0.13.5
  # other dependencies

dev_dependencies:
  build_runner: ^2.3.2
  json_serializable: ^6.5.4
  # other dependencies

Then you should create a model with the fromJson method. This is going to be used to deserialize the JSON you retrieve from the API call. I'm going to use a Dart file named user.dart

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  const User({
    required this.id,
    required this.name,
    required this.username,
    required this.email,
  });

  final int id;
  final String name;
  final String username;
  final String email;

  /// Connect the generated [_$UserFromJson] function to the `fromJson`
  /// factory.
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  /// Connect the generated [_$UserToJson] function to the `toJson` method.
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

Now in your Terminal you should run flutter pub run build_runner build --delete-conflicting-outputs to build the generated file, in my case it will generate a file called user.g.dart.

Now you need a service to make the HTTP call an return the list of users, I'm going to create a file called users_service.dart

import 'dart:convert';

import 'package:stackoverflow/user.dart';
import 'package:http/http.dart' as http;

class UsersService {
  Future<List<User>> getUsers() async {
    final uri = Uri.parse('https://jsonplaceholder.typicode.com/users');
    final response = await http.get(uri);
    final responseString = response.body;
    final jsonList = List.from(jsonDecode(responseString));
    return jsonList.map((json) => User.fromJson(json)).toList();
  }
}

Here you must focus on the jsonDecode method that converts the JSON to a Dart object, and in the User.fromJson method that deserializes the JSON object converting it into a valid User Dart class

  • Related