Auto-generate class and member from json file in Flutter - json

I have a simple json file like below. This is fixed in the project.
{
"en": "English",
"es": "Español",
"fr": "Français"
}
My question is, is it possible to do a auto-generate work to create a class with members which return the value of each key? The result of the auto-generate can be similar to below example. So every time I add new key and value to the json file, this class will generate or update that new item into it.
class JsonHelper {
static String get en => json['en'];
static String get es => json['es'];
static String get fr => json['fr'];
}

you can use this site for Auto-generate class in Flutter:
https://app.quicktype.io/?share=pxoAci2ZiiPtLyjXaYhD
another way is using Auto-generator package of npm
New Edit: I just found this site: https://jsontodart.com/

Yes for sure you can use Auto-generate class in Flutter on this website: Instantly parse Json
Example
// To parse this JSON data, do
//
// final autoGenerate = autoGenerateFromJson(jsonString);
import 'dart:convert';
AutoGenerate autoGenerateFromJson(String str) => AutoGenerate.fromJson(json.decode(str));
String autoGenerateToJson(AutoGenerate data) => json.encode(data.toJson());
class AutoGenerate {
AutoGenerate({
this.en,
this.es,
this.fr,
});
String en;
String es;
String fr;
factory AutoGenerate.fromJson(Map<String, dynamic> json) => AutoGenerate(
en: json["en"],
es: json["es"],
fr: json["fr"],
);
Map<String, dynamic> toJson() => {
"en": en,
"es": es,
"fr": fr,
};
}
you can then simply use final objectFromClass = autoGenerateFromJson(jsonString)

Related

How can I update/add new information to my local JSOn file in Flutter? (without creating any classes)

I made a small application, sort of like a library app where you can add books you've read. So, I have a local JSON file, which looks like this:
[
{
"name": "Harry Potter and the Deathly Hallows",
"author": "J.K. Rowling",
"rating": "4.5",
"category": "Fantasy",
"url": "some url"
},
{
"name": "For Whom The Bell Tolls",
"author": "E. Hemingway",
"rating": "4",
"category": "Novel",
"url": "some url#2"
}
]
In my main.dart file I have a function that reads my JSON file, decodes and loads it in a list named "data":
readData(){
DefaultAssetBundle.of(context).loadString("json/books.json").then((s){
setState(() {
data = json.decode(s);
});
});
}
#override
void initState() {
super.initState();
readData();
}
I can easily add new books to "data" and everything is fine except for one thing, - I don't know how to update/write information to JSON, so the app could show me the updated list with the new book after a restart. I've added. How do I do this? And what should I write into the JSON file, - the updated List with all books or just a Map with a new book?
Answer to NelsonThiago
This code is in "class AddingPageState extends State":
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/books.json');
}
Future<File> writeData(List list) async { // "list" is the updated book-list
final file = await _localFile;
String encodedData = jsonEncode(list);
return file.writeAsString('$encodedData');
}
And I call "writeData" in onPressed function.
It would be better to make this using a local NoSql database like sembast, this way you could add, delete and update your data. But as you are already working with json, You just need to encode your new changed data to json and write to the file again.
To write and read files, instead of using rootBundle read this read and write files.
As I can see from your JSON file, you are storing the Books as a list of JSON objects, which will make things easier.
But your request of solving this without adding new classes is a bit strange because adding a Book class in your case would make things much easier.
So I am going to give you a solution that assumes that you create a new Book class.
Start by reading the file as you are currently doing.
Store the content of the file in a List of dynamic List.
Iterate through the list using the map function, add using the from JSON function in the Book class decode the JSON to a book object, then apply the toList() function on that map.
Return the result to your UI and treat it as any other list.
When you want to add a new Book, create a new object of the book class and add it to your list.
When the user finishes adding, transform the list to a JSON object agian and store it in the file again;
Something like this:
The Book Class:
class Book {
String? name;
String? author;
String? rating;
String? category;
String? url;
Book({
required this.name,
required this.author,
required this.rating,
required this.category,
required this.url,
});
Book.fromJson(Map<String, dynamic> json) {
name = json['name'];
author = json['author'];
rating = json['rating'];
category = json['category'];
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['author'] = this.author;
data['rating'] = this.rating;
data['category'] = this.category;
data['url'] = this.url;
return data;
}
#override
String toString() {
return 'Book(name: $name, author: $author, rating: $rating, category: $category, url: $url)';
}
}
And main function
void main() {
/// read the file the way you like
List<dynamic> list = [
{
"name": "Harry Potter and the Deathly Hallows",
"author": "J.K. Rowling",
"rating": "4.5",
"category": "Fantasy",
"url": "some url"
},
{
"name": "For Whom The Bell Tolls",
"author": "E. Hemingway",
"rating": "4",
"category": "Novel",
"url": "some url#2"
}
];
List<Book> books = list
.map(
(jsonObject) => Book.fromJson(jsonObject),
)
.toList();
print(books);
Book newBook = Book(
name: 'Some Book',
author: 'Some Author',
rating: 'Some rating',
category: 'Some category',
url: 'Some Url');
books.add(newBook);
print(books);
books
.map(
(book) => book.toJson(),
)
.toList();
//Write the the file again to storage or anywhere else
}
See the following example. But it requires to create a class. The sample json file is like below (pretty much similar to your json file) -
[
{"name":"Ash","age":"22","hobby":"golf"},
{"name":"philip","age":"17","hobby":"fishing"},
{"name":"charles","age":"32","hobby":"drawing"},
]
And I am editing the above code answered by Ward Suleiman so that you can read from a local json file and write to it-
import 'dart:io';
import 'dart:convert';
List<Player> players = [];
void main() async{
print("hello world");
final File file = File('D:/Sadi/.../test.json'); //load the json file
await readPlayerData(file); //read data from json file
Player newPlayer = Player( //add a new item to data list
'Samy Brook',
'31',
'cooking'
);
players.add(newPlayer);
print(players.length);
players //convert list data to json
.map(
(player) => player.toJson(),
)
.toList();
file.writeAsStringSync(json.encode(players)); //write (the whole list) to json file
}
Future<void> readPlayerData (File file) async {
String contents = await file.readAsString();
var jsonResponse = jsonDecode(contents);
for(var p in jsonResponse){
Player player = Player(p['name'],p['age'],p['hobby']);
players.add(player);
}
}
And the Player class -
class Player {
late String name;
late String age;
late String hobby;
Player(
this.name,
this.age,
this.hobby,
);
Player.fromJson(Map<String, dynamic> json) {
name = json['name'];
age = json['age'];
hobby = json['hobby'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['age'] = this.age;
data['hobby'] = this.hobby;
return data;
}
}

How to corect toJson converter in freezed lib for dart/flutter

When trying to convert, the Profile class is not converted correctly. Exited as the result of the toString () function.
Person.dart
import 'package:adminapp/domains/Test/Profile.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'Person.freezed.dart';
part 'Person.g.dart';
#freezed
class Person with _$Person {
factory Person({
String? id,
Profile? profile,
}) = _Person;
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
}
Profile.dart
import 'package:freezed_annotation/freezed_annotation.dart';
part 'Profile.freezed.dart';
part 'Profile.g.dart';
#freezed
class Profile with _$Profile {
factory Profile({
DateTime? bDay,
String? hob,
String? rel,
}) = _Profile;
factory Profile.fromJson(Map<String, dynamic> json) =>
_$ProfileFromJson(json);
}
main.dart
import 'package:adminapp/domains/Test/Person.dart';
import 'package:adminapp/domains/Test/Profile.dart';
void main(List<String> args) {
Person p = Person(
id: '4',
profile: Profile(
bDay: DateTime.now(),
hob: "123",
rel: 'asd',
));
print(p.toJson());
}
output:
{id: 4, profile: Profile(bDay: 2021-07-28 08:42:51.708857, hob: 123, rel: asd)}
But it's not json format! Profile class convert dont corect!
And I cant save it to firestore!
Your desired valid json string:
{id: 4, profile: {bDay: 2022-08-08T14:54:11.781502, hob: 123, rel: asd}}
From documentation:
In order to serialize nested lists of freezed objects, you are
supposed to either specify a #JsonSerializable(explicitToJson: true)
or change explicit_to_json inside your build.yaml file.
After in generated class will be one small change, pls see the pic below:

Got the error in Fultter 'Try correcting the name to an existing named parameter's name' which try to import class models

I just create class Table in flutter models and now try to assign in json form. I create class Table from quicktype which I got as below
// To parse this JSON data, do
//
// final table = tableFromJson(jsonString);
import 'dart:convert';
Table tableFromJson(String str) => Table.fromJson(json.decode(str));
String tableToJson(Table data) => json.encode(data.toJson());
class Table {
Table({
this.name,
this.seat,
});
String name;
String seat;
factory Table.fromJson(Map<String, dynamic> json) => Table(
name: json["name"],
seat: json["seat"],
);
Map<String, dynamic> toJson() => {
"name": name,
"seat": seat,
};
}
Now I try to assign name and seat but got the error
Table data = Table(name: inputTable.text, seat: inputSeat.text);
http.Response response = await Connect().post('table/create/', data);
}
My error is
The named parameter 'name' isn't defined.
Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'name'.
You should change your classname and constructor name as they can be reversed classes of material

how to encode and send to server json list by dio

i have class that generate json list this is my class
class Tool{
String Name;
bool selection;
String englishName;
Map<String, dynamic> toJson() {
return {
'Name': persianName,
'selection': selection,
'englishName': englishName
};
}
}
List<Tool> tools=new List();
setTool(tool){
tools.add(tool);
}
toolsLength(){
return tools.length;
}
updatetool(index,goal){
tools[index]=goal;
}
getTool(index){
return tools[index];
}
getAllTools(){
return tools;
}
and this is dio library that send my list to server every thing is ok but my array is into Double quotation in other word my list is string how to pick up double quotation around of json array . if assume my json array hase
"tools": [{"name":"jack","selection" : false " ,"englishName":"jock"}]
result is :
"tools": "[{"name":"jack","selection" : false " ,"englishName":"jock"}]"
how fix it this is my class for send
FormData formData = new FormData.from({
"tools":jsonEncode(getAllTools().map((e) => e.toJson()).toList()) ,
});
response = await
dio.post("${strings.baseurl}/analyze/$username/$teacher", data:
formData);
print("----------> response is :"+response.toString());
Edit
You can paste the following code to DarPad https://dartpad.dartlang.org/
The following demo shows transform your Json String to Tool List and Convert your Tool List to JSON string again and use map.toJson
var yourresult = toolList.map((e) => e.toJson()).toList();
you can see result in picture
use FormData.from need to know what your api's correct JSON String.
Please test your web api with Postman, if you success, you will know correct format string.
In your code
FormData formData = new FormData.from({
"tools":jsonEncode(getAllTools().map((e) => e.toJson()).toList()) ,
});
if you are trying to to do
FormData formData = new FormData.from({
"tools":'[{"name":"jack","selection" : false ,"englishName":"jock"}, {"name":"jack2","selection" : false ,"englishName":"jock2"}]' ,
});
so you can get your json string first and put it in FormData
var toolsJson = toolsToJson(toolList);
FormData formData = new FormData.from({
"tools":toolsJson ,
});
full demo code, you can paste to DartPad to see string and list conversion
import 'dart:async';
import 'dart:io';
import 'dart:core';
import 'dart:convert';
class Tools {
String name;
bool selection;
String englishName;
Tools({
this.name,
this.selection,
this.englishName,
});
factory Tools.fromJson(Map<String, dynamic> json) => new Tools(
name: json["name"],
selection: json["selection"],
englishName: json["englishName"],
);
Map<String, dynamic> toJson() => {
"name": name,
"selection": selection,
"englishName": englishName,
};
}
main() {
List<Tools> toolsFromJson(String str) => new List<Tools>.from(json.decode(str).map((x) => Tools.fromJson(x)));
String toolsToJson(List<Tools> data) => json.encode(new List<dynamic>.from(data.map((x) => x.toJson())));
var toolsStr = '[{"name":"jack","selection" : false ,"englishName":"jock"}, {"name":"jack2","selection" : false ,"englishName":"jock2"}]';
var toolList = toolsFromJson(toolsStr);
var toolsJson = toolsToJson(toolList);
print("toolsJson ${toolsJson} \n");
var toolsmap = toolList[0].toJson();
print("toolsmap ${toolsmap.toString()}\n");
var yourresult = toolList.map((e) => e.toJson()).toList();
print(yourresult.toString());
}
you can paste your JSON string to https://app.quicktype.io/, you will get correct Dart class
correct JSON string of your sample. in false keyword followed by a " cause JSON string parsing error.
[
{"name":"jack",
"selection" : false ,
"englishName":"jock"
}
]
code to parse JSON string and encode to List, use toJson will convert to JSON string you need to send with dio form
// To parse this JSON data, do
//
// final tools = toolsFromJson(jsonString);
import 'dart:convert';
List<Tools> toolsFromJson(String str) => new List<Tools>.from(json.decode(str).map((x) => Tools.fromJson(x)));
String toolsToJson(List<Tools> data) => json.encode(new List<dynamic>.from(data.map((x) => x.toJson())));
class Tools {
String name;
bool selection;
String englishName;
Tools({
this.name,
this.selection,
this.englishName,
});
factory Tools.fromJson(Map<String, dynamic> json) => new Tools(
name: json["name"],
selection: json["selection"],
englishName: json["englishName"],
);
Map<String, dynamic> toJson() => {
"name": name,
"selection": selection,
"englishName": englishName,
};
}

how to update json data using flutter

how to update JSON value. I am using flutter with a REST API to change the data but I'm struggling how to refresh my JSON data sorry friends I don't know much about the flutter so please help me out about it please find JSON'S Object below:
{
id: 1,
clef: "Y8F5eEo0",
IndiceSensibilite: "0.04",
Objectif: "1.00"
}
I want to update the value of IndiceSensibilite using a textField.
I m here for more clarification.
i will be very thankful if there's someone who gonna help me.
You can transform the JSON into an Object, make your modifications and back to JSON:
import 'dart:convert'; // make sure you imported this library
String jsonValue = '{"id": 1, "clef": "Y8F5eEo0", "indiceSensibilite": "0.04", "objectif": "1.00" }'; // original JSON
Use a Future to convert it into Object:
Future<ToObject> jsonToObject() async {
var parse = json.decode(jsonValue);
return ToObject.parseJson(parse);
}
and your Object (ToObject in my case) will have the following model and methods:
class ToObject {
int id;
String clef;
String indiceSensibilite;
String objectif;
ToObject({this.id, this.clef, this.indiceSensibilite, this.objectif});
factory ToObject.parseJson(Map<String, dynamic> json) => ToObject(
id: json['id'], clef: json['clef'], indiceSensibilite: json['indiceSensibilite'], objectif: json['objectif']);
Map<String, dynamic> toJson() =>
{'id': id, 'clef': clef, 'indiceSensibilite': indiceSensibilite, 'objectif': objectif};
}
I used a FutureBuilder to get the data, modify the value and back to JSON:
FutureBuilder<ToObject>(
future: jsonToObject(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
var object = snapshot.data;
object.indiceSensibilite = "43.00";
return Text(json.encode(object.toJson()));
} else {
return Text("Loading...");
}
},
)
Your end result is a modified JSON to use as you wish: