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