'Creating a list of objects from a nested JSON in Flutter
There's a URL address that I decoded to JSON, and there's a certain header (result) that I'm trying to convert to a list of objects (Book).
When I print the content of this header I do get the desired result (first print), but when I create the list and try to print one of the fields of the first object in the list nothing is printed (second print).
Which means there's a problem with the way I create the list and I can't find it.
I would really appreciate your help.
The JSON structure:
{count: 9447, result: [{book_about: string, book_label: string, book_wikilink: string, fragments: [string1, string2, string3, string4], id: string, label: string, text: string]}
An image of it: https://i.stack.imgur.com/w2JGm.png
My code:
Future<List<Book>> fetchBooks(http.Client client) async {
var url = 'http://jbse.cs.technion.ac.il:3030/search?query=אברהם&start=0';
final response = await http.get(Uri.parse(url),headers: {'Content-Type': 'application/json'});
Map<String, dynamic> responseBody = jsonDecode(response.body);
dynamic results = responseBody['result'];
print(results);
List<Book> list = results.map((book) => Book.fromJson(book)).toList();
print(list.first.book_wikilink);
return list;
}
class Book {
String book_about;
String book_label;
String book_wikilink;
List<String> fragments;
String id;
String label;
String text;
Book(
this.book_about,
this.book_label,
this.book_wikilink,
this.fragments,
this.id,
this.label,
this.text
);
factory Book.fromJson(Map<String, dynamic> json) {
return Book(
json['book_about'],
json['book_label'],
json['book_wikilink'] ,
json['fragments'],
json['id'],
json['label'],
json['text'],
);
}
}
Solution 1:[1]
You can do it manually.
Select and convert what you want on the fly (during parsing).
import 'package:fast_json/fast_json_selector.dart' as parser;
import 'package:http/http.dart' as http;
void main(List<String> args) async {
final books = await fetchBooks();
print('Found: ${books.length} book(s).');
print(books.map((e) => e.label).join('\n'));
}
Future<List<Book>> fetchBooks() async {
var url = 'http://jbse.cs.technion.ac.il:3030/search?query=?????&start=0';
final response = await http
.get(Uri.parse(url), headers: {'Content-Type': 'application/json'});
return _findBooks(response.body);
}
List<Book> _findBooks(String source) {
// Path to Book
// Map => property "result" => List => list index => Map (Book)
final level = '{} result [] 0 {}'.split(' ').length;
final books = <Book>[];
void select(parser.JsonSelectorEvent event) {
if (event.levels.length == level) {
final book = Book.fromJson(event.lastValue as Map);
books.add(book);
// Freeing the memory allocated for the book
// because it is no longer needed
event.lastValue = null;
}
}
parser.parse(source, select: select);
return books;
}
class Book {
String book_about;
String book_label;
String book_wikilink;
List<String> fragments;
String id;
String label;
String text;
Book(this.book_about, this.book_label, this.book_wikilink, this.fragments,
this.id, this.label, this.text);
factory Book.fromJson(Map json) {
return Book(
json['book_about'] as String,
json['book_label'] as String,
json['book_wikilink'] as String,
(json['fragments'] as List).cast(),
json['id'] as String,
json['label'] as String,
json['text'] as String,
);
}
}
Output:
Found: 10 book(s).
????? ??? ???? ??
???? ??? ?????? ?? ??
??"? ?????? ?? ??
??? ????? ?????? ?? ??
??? ??? ???? ?????? ?? ??
?????? ?????? ?? ??
??"? ?????? ?? ??
???? ????? ?????? ?? ??
???? ??? ?????? ?? ??
???"? ?????? ?? ??
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
