How to deserialize the dynamic key json in flutter? - json

I want to deserialize the JSON file but I have no idea how to build a model from this file. I want to know if my code is right or wrong
{
"Thriller": [
{
"Death Clique": "https://www.youtube.com/watch?v=4Q9lTjqQeBU&ab_channel=VMovies"
},
{
"CID": "https://www.youtube.com/watch?v=4Q9lTjqQeBU&ab_channel=VMovies"
},
{
"Wrong Turn": "https://www.youtube.com/watch?v=9spc-dExLH0&ab_channel=SagarForever"
},
],
"Action Movie": [
{
"Nobody": "https://nobodymovie.com"
},
{
"Tenet": "https://tenetmovie.com"
},
],
"Romantic Movie": [
{
"Titanic": "https://titanicmovie.com"
},
{
"The Vow": "https://thevowmovie.com"
},
]
}
I have built this model to fetch keys like (thriller, action movie,) to display in the list and inside list to display the values (movie name) in grid view.
class MovieCategories {
final String? title;
final List<Movie>? subServices;
MovieCategories({ this.title, this.subServices});
factory MovieCategories.fromJson(Map<String, dynamic> json) {
var list = json.values as List;
List<Movie> imagesList = list.map((i) => Movie.fromJson(i)).toList();
return MovieCategories(
title: json.keys.toString(),
subServices: imagesList,
);
}
}
class Movie {
final String? title;
final String? url;
Movie({this.title, this.url});
factory Movie.fromJson(Map<String, dynamic> parsedJson){
return Movie(
title:parsedJson.keys.toString(),
url:parsedJson.values.toString()
);
}
}

I'd also recommend following the proper key-value-pair JSON convention, as in:
{
[
{
"genre":"thriller",
"movies": [
{
"title": "Nobody",
"url": "https://nobodymovie.com"
},
{
"title": "Tenet",
"url": "https://tenetmovie.com"
}
]
...
}
That way the mapping would be much more straight-forward:
class Movie {
final String? title;
final String? url;
Movie({this.title, this.url});
factory Movie.fromJson(Map<String, dynamic> parsedJson){
return Movie(
title: parsedJson['title'],
url: parsedJson['url']
);
}
}
And your MovieCategories*:
class MovieCategories {
final String? genre;
final List<Movie>? movies;
MovieCategories({this.genre, this.movies});
factory MovieCategories.fromJson(
String cat, <Map<String, String> genre) {
return MovieCategories(
genre: genre['genre'],
movies: genre['movies'].map((m) => Movie.fromJson(m)).toList(),
);
}
}

If your data are constant like that then you can try this code.
import 'dart:convert';
/// Map<String, List<Map<String, String>>>
class MovieCategories {
final String? title;
final List<Movie>? subServices;
MovieCategories({this.title, this.subServices});
factory MovieCategories.fromJson(
String cat, List<Map<String, String>>? movies) {
return MovieCategories(
title: cat,
subServices: movies?.map((m) => Movie.fromJson(m)).toList(),
);
}
static List<MovieCategories> fromJsonMaps(String jsonString) {
final _listOfMovies =
Map<String, List<Map<String, String>>>.from(jsonDecode(jsonString));
return _listOfMovies.keys
.map((cat) => MovieCategories.fromJson(cat, _listOfMovies[cat]))
.toList();
}
}
class Movie {
final String? title;
final String? url;
Movie({this.title, this.url});
factory Movie.fromJson(Map<String, String> parsedJson) {
return Movie(title: parsedJson.keys.first, url: parsedJson.values.first);
}
}

Related

Flutter model how to get information from an object nested in an array?

For example, JSON looks like this:
{
"id": 12151,
"cadastres":[
{
"general_info": {
"area": 1515,
"datev": "20.12.20"
}
},
{
"general_info": {
"area": 1151,
"datev": "10.12.10"
}
}
]
}
I want to get each of these values.
I created a model:
class Cadastre {
final int id;
final double area;
final String creationDate;
Cadastre(
{required this.id,
required this.area,
required this.creationDate});
factory Cadastre.fromJson(Map<String, dynamic> map) {
return Cadastre(
id: map['id'],
area: map['area'],
creationDate: map['datev'],);
}
}
In this way, I would get only the ID correctly, how can I get data for the model from an object nested in an array?
Your JSON returns an id and a list of cadastre objects. If you want to have a reference of the id in each model, I will suggest this implementation:
class Cadastre {
final int id;
final double area;
final String creationDate;
Cadastre({
required this.id,
required this.area,
required this.creationDate,
});
/*
You will use it like this:
final cadastres = Cadastre.fromJsonList(json['id'], json['cadastres']);
*/
static List<Cadastre> fromJsonList(int id, List<Map<String, dynamic>> list) {
return list.map((map) {
map.putIfAbsent("id", () => id);
return Cadastre.fromJson(map);
}).toList();
}
factory Cadastre.fromJson(Map<String, dynamic> map) {
return Cadastre(
id: map["id"],
area: map['area'],
creationDate: map['datev'],
);
}
}

How to retrieve Json Data stored locally in flutter

Here is my controller code
class PackageController extends GetxController {
PackageController({Key? key});
List<dynamic> _packageList = [];
List _items = [];
List<dynamic> get packageList => _packageList;
void getPackageList() {
_packageList = [];
_packageList.addAll(PackageModel.fromJson(_items).packages);
}
Future<void> readJson() async {
final String response = await rootBundle.loadString('local/packages.json');
final data = await json.decode(response);
_items = data["packages"];
update();
}
//end
}
but am faced with this issue
Here is my Model that controls the fromJson data in the package controller of the project.
class PackageModel {
PackageModel({
required this.packages,
});
late final List<Packages> packages;
PackageModel.fromJson(Map<String, dynamic> json) {
packages =
List.from(json['packages']).map((e) => Packages.fromJson(e)).toList();
}
}
class Packages {
Packages({
required this.id,
required this.name,
required this.description,
required this.price,
required this.img,
});
late final int id;
late final String name;
late final String description;
late final String price;
late final String img;
Packages.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
description = json['description'];
price = json['price'];
img = json['img'];
}
}
Here is the json data
{
"packages": [
{
"id": 1,
"name": "VIP 1",
"description": "",
"price": "10",
"img": ""
}
]
}
I am trying how to retrieve Json Data stored locally in flutter but I ran into a problem, I need help

How to read objects from Json File in dart and Map to variables?

I have a JSON file with different and unique objects as Employee1, employee2 and so on. Now I want to read the JSON file using the unique objects and then map the object contents to a variable and use it in my project.
the JSON file is as follows:
[
{
"employee1": {
"firstName": "Lokesh",
"lastName": "Gupta",
"website": "howtodoinjava.com"
}
},
{
"employee2": {
"firstName": "Brian",
"lastName": "Schultz",
"website": "example.com"
}
}
]
Just check out this example that I have created:
Following is the json that you provided.
[
{
"employee1": {
"firstName": "Lokesh",
"lastName": "Gupta",
"website": "howtodoinjava.com"
}
},
{
"employee2": {
"firstName": "Brian",
"lastName": "Schultz",
"website": "example.com"
}
}
]
This is the solution :
import 'dart:convert';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: HomePage());
}
}
class Employee {
String firstName;
String lastName;
String website;
Employee({this.firstName, this.lastName, this.website});
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool _isLoading = false;
List<Employee> employeeList = List();
#override
void initState() {
super.initState();
getData();
}
getData() async {
String data =
await DefaultAssetBundle.of(context).loadString("json/parse.json");
var jsonData = json.decode(data);
jsonData.forEach((item) {
item.forEach((key, value) {
employeeList.add(Employee(
firstName: value['firstName'],
lastName: value['lastName'],
website: value['website']));
});
});
print(employeeList.length);
employeeList.forEach((item) {
print(item.firstName);
print(item.lastName);
print(item.website);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(body: Text(''));
}
}
Let me know if it works.
feed the above json list to json.decode()
var dJson = json.decode(list);
//which results in dJson being a List<dynamic>
//access the first result
var first = dJson[0];
//which gives you a Map because the json.decode maintains the structure of the json given
var employee1 = first["employee1"];
//will give you another Map
var firstName = employee1["firstName"];
//will give you the firstName
print(firstName);//Lokesh
First, try to create a model out of the JSON you are getting. For the sample provide the Model, would look like this.
class EmployeeModel {
Employee1 employee1;
EmployeeModel({this.employee1});
EmployeeModel.fromJson(Map<String, dynamic> json) {
employee1 = json['employee1'] != null
? new Employee1.fromJson(json['employee1'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.employee1 != null) {
data['employee1'] = this.employee1.toJson();
}
return data;
}
}
class Employee1 {
String firstName;
String lastName;
String website;
Employee1({this.firstName, this.lastName, this.website});
Employee1.fromJson(Map<String, dynamic> json) {
firstName = json['firstName'];
lastName = json['lastName'];
website = json['website'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['website'] = this.website;
return data;
}
}
Then use
EmployeeModel employee = EmployeeModel.fromJson(responseJSON);
to access the values within the model.

Access nested objects in json using json_serializable in Dart

Trying to convert my json to objects in Dart/Flutter using the json_serializable. I cannot seem to find a way to access a nested ID (data is coming from MongoDB thus the $ in the json).
Here is the json:
{
"_id": {
"$oid": "5c00b227" <-- this is what I am trying to access
},
"base": 1,
"tax": 1,
"minimum": 5,
"type": "blah"
}
Result:
class Thing {
final int id;
final String base;
final String tax;
final String type;
final int minimum;
}
It is not possible with json_serializable package itself. You have to create separate objects for getting this nested data.
Look the discussion here
https://github.com/google/json_serializable.dart/issues/490
But, there is possible way to get nested fields with added converter (solution was found here https://github.com/google/json_serializable.dart/blob/master/example/lib/nested_values_example.dart)
import 'package:json_annotation/json_annotation.dart';
part 'nested_values_example.g.dart';
/// An example work-around for
/// https://github.com/google/json_serializable.dart/issues/490
#JsonSerializable()
class NestedValueExample {
NestedValueExample(this.nestedValues);
factory NestedValueExample.fromJson(Map<String, dynamic> json) =>
_$NestedValueExampleFromJson(json);
#_NestedListConverter()
#JsonKey(name: 'root_items')
final List<String> nestedValues;
Map<String, dynamic> toJson() => _$NestedValueExampleToJson(this);
}
class _NestedListConverter
extends JsonConverter<List<String>, Map<String, dynamic>> {
const _NestedListConverter();
#override
List<String> fromJson(Map<String, dynamic> json) => [
for (var e in json['items'] as List)
(e as Map<String, dynamic>)['name'] as String
];
#override
Map<String, dynamic> toJson(List<String> object) => {
'items': [
for (var item in object) {'name': item}
]
};
}
try this,
class Thing {
int id;
String base;
String tax;
String type;
int minimum;
Thing({
this.id,
this.base,
this.tax,
this.type,
this.minimum,
});
factory Thing.fromJson(Map<String, dynamic> json) {
return Thing(
id: json['_id']["oid"],
base: json['base'].toString(),
tax: json['tax'].toString(),
type: json['type'].toString(),
minimum: json['minimum'],
);
}
}

How to customize json_serializable library code generation?

I use json_serializable library and firebase for database. I need to serialize and deserialize my data class to/from JSON. But firebase json format looks like this
{
'some_id_here': {
'title': 'some_title',
'content': 'some_content',
'timestamp': 'some_timestamp'
}, ...
}
Here's my class
import 'package:json_annotation/json_annotation.dart';
part 'update.g.dart';
#JsonSerializable()
class Update {
final String id, title, content, timestamp;
Update({this.id, this.title, this.content, this.timestamp});
factory Update.fromJson(Map<String, dynamic> json) => _$UpdateFromJson(json);
Map<String, dynamic> toJson() {
return _$UpdateToJson(this);
}
}
So how to customize the toJson() function so I can deserialize from
Update('ID', 'TITLE', 'CONTENT', 'TIMESTAMP');
to
{
'ID': {
'title': 'TITLE',
'content': 'CONTENT',
'timestamp': 'TIMESTAMP'
}
}
Try this
class ID {
String title;
String content;
String timestamp;
Map<String, dynamic> toJson() {
final Map<String, dynamic> ID = new Map<String, dynamic>();
ID['title'] = this.title;
ID['content'] = this.content;
ID['timestamp'] = this.timestamp;
return ID;
}
}