I try to display json as image. But instead image, it triggers error. I have tried to change the code but it didn't work.
class _MainPage extends State<MainPage> {
Future<List<Data>> _fetchData() async {
final jsondata =
await rootBundle.rootBundle.loadString('assets/datakomik.json');
final list = json.decode(jsondata)["data"] as List<dynamic>;
return list.map((e) => Data.fromJson(e)).toList();
}
Future<List<KomikModel>> _listKomik() async {
final jsongambar =
await rootBundle.rootBundle.loadString('assets/datakomik.json');
final list = json.decode(jsongambar)["image"] as List<dynamic>; <-- Error is in this line
return list.map((e) => KomikModel.fromJson(e)).toList();
}
Here is datakomik.json where I set the json. The data that I want to display is "judul" and "image" that contains title and picture of the comic. I only know that I can only set one data after (jsongambar), so I only set ["image"] after it. But it triggers an error like I've said.
{
"data": [
{
"kategori": "Update terbaru",
"data": [
{
"judul": "Jujutsu Kaisen",
"image": "images/Jujutsu Kaisen_Volume 1.webp"
},
{
"judul": "Vinland Saga",
"image": "images/Vinland Saga_volume 01.jpg"
},
{
"judul": "Hunter x Hunter",
"image": "images/HxH_Volume 10.jpg"
},
{
"judul": "One Piece",
"image": "images/One Piece_Volume 1.webp"
}
]
},
{
"kategori": "Action",
"data": [
{
"judul": "Bleach",
"image": "images/Bleach-volume-73.jpg"
},
{
"judul": "Naruto",
"image": "images/naruto_volume 63.jpg"
},
{
"judul": "Dragon Ball Super",
"image": "images/dragon-ball-super_volume 14.webp"
},
{
"judul": "Hunter x Hunter",
"image": "images/HxH_Volume 10.jpg"
},
{
"judul": "One Punch Man",
"image": "images/one punch man_volume 25.jpg"
},
{
"judul": "My Hero Academia",
"image": "images/My Hero Academia_volume 4.jpg"
}
]
},
{
"kategori": "Baru dibaca",
"data": [
{
"judul": "Kaguya-sama: Love is War",
"image": "images/kaguya-sama_Volume 22.jpg"
}
]
}
]
}
This is where I call _listKomik()
FutureBuilder<List<KomikModel>>(
future: _listKomik(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
This is where I set a getter for image
return Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8),
height: 270,
child: ListView(
scrollDirection: Axis.horizontal,
children: snapshot.data!
.map((_data) => Column(
children: <Widget>[
Card(
child: Text(_data.image.toString()), <-- image getter
),
],
))
.toList(),
),
),
],
);
CodePudding user response:
This method will give you a list of image URLs from JSON.
Future<List<Map<String,String>>> _listKomik() async {
final jsongambar =
await rootBundle.rootBundle.loadString('assets/datakomik.json');
final list = jsongambar["data"] as List<dynamic>;
List<Map<String,String>> imageList = [];
list.forEach((element) {
final data = element["data"] as List<dynamic>;
for (var value in data) {
imageList.add({"image":value["image"],"name":value["image"]});
}
});
return imageList;}
also change this code as well
FutureBuilder<List<Map<String,String>>(
future: _listKomik(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
and if you want show image then you can use snapshot.data["image"] or snapshot.data["name"]
CodePudding user response:
I am not sure of the structure of KomikModel so i've made a best guess
Future<List<KomikModel>> _listKomik() async {
final jsongambar =
await rootBundle.rootBundle.loadString('assets/datakomik.json');
final list = json.decode(jsongambar) as Map<String, dynamic>;
final komiks = list['data'] as List<dynamic>;
return komiks
.map((e) => KomikModel.fromMap(e as Map<String, dynamic>))
.toList();
}
class KomikModel {
final String kategori;
final List<Manga> data;
KomikModel({
required this.kategori,
required this.data,
});
Map<String, dynamic> toMap() {
return {
'kategori': kategori,
'data': data.map((x) => x.toMap()).toList(),
};
}
factory KomikModel.fromMap(Map<String, dynamic> map) {
return KomikModel(
kategori: map['kategori'],
data: List<Manga>.from(map['data']?.map((x) => Manga.fromMap(x))),
);
}
String toJson() => json.encode(toMap());
factory KomikModel.fromJson(String source) =>
KomikModel.fromMap(json.decode(source));
}
class Manga {
final String judul;
final String image;
Manga({
required this.judul,
required this.image,
});
Map<String, dynamic> toMap() {
return {
'judul': judul,
'image': image,
};
}
factory Manga.fromMap(Map<String, dynamic> map) {
return Manga(
judul: map['judul'],
image: map['image'],
);
}
String toJson() => json.encode(toMap());
factory Manga.fromJson(String source) => Manga.fromMap(json.decode(source));
}
You can access image as normal through KomikModel
final <List<KomikModel>> komiks = await _listKomiks();
print(komiks[0].data[0].image);
// or a list of all images in a komik
final <List<String>> images = komiks[0].data.fold<List<String>>(
[], (prev, manga) => [...prev, manga.image])
or any other way you would normaly access a Future in Flutter.