This might be a bit of broad question.
I have an JSON Map Array which i can parse normally. But i would like to MAP multiple Values to a Single key. I am stuck and unsure how to proceed.
My JSON output. I cannot change this.
{
"pos":"1",
"element":"37542",
"title":"Easy On Me",
"inter":"Adele",
"isnew":"0"
},
{
"pos":"66",
"element":"37183",
"title":"Send My Love",
"inter":"Adele",
"isnew":"0"
}
this is just a snippet of the actual JSON objects
what I would like to do is something like Map<String,List<String,String>>
Adele
- Easy On Me, 37542
- Send My Love, 37183
Searching online I find a lot of examples how to parse JSON normally, but never found a version where you can iterate through a JSON version like above and pull parts of the map out and add it to another.
any help would be appreciated. Thank you in advance
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:async';
class SongList {
final List<Song> songs;
SongList({
required this.songs,
});
factory SongList.fromJson(List<dynamic> parsedJson) {
List<Song> songs = <Song>[];
songs = parsedJson.map((i) => Song.fromJson(i)).toList();
return SongList(songs: songs);
}
}
class Song {
final String? pos;
final String? element;
final String? title;
final String? inter;
final String? isnew;
const Song(
{required this.pos,
required this.element,
required this.title,
required this.inter,
required this.isnew});
factory Song.fromJson(Map<String, dynamic> data) {
return Song(
pos: data['pos'] as String?,
element: data['element'] as String?,
title: data['title'] as String?,
inter: data['inter'] as String?,
isnew: data['isnew'] as String?,
);
}
}
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
class Songs extends StatefulWidget {
final String pos;
final String element;
final String title;
final String inter;
final String isnew;
const Songs(
{super.key,
required this.pos,
required this.element,
required this.title,
required this.inter,
required this.isnew});
@override
State<Songs> createState() => _SongsState();
}
class _SongsState extends State<Songs> {
late AudioPlayer player;
@override
void initState() {
super.initState();
player = AudioPlayer();
}
@override
void dispose() {
player.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var titles = Row(
mainAxisSize: MainAxisSize.min,
children: [
Column(children: [
SizedBox(
height: 25,
width: 200,
child: Text(
widget.title,
style: const TextStyle(fontSize: 14),
textAlign: TextAlign.center,
),
),
SizedBox(
height: 25,
width: 200,
child: Text(
widget.inter,
style: const TextStyle(fontSize: 10),
textAlign: TextAlign.center,
),
),
]),
],
);
return FittedBox(
fit: BoxFit.contain,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
Center(
child: SizedBox(
height: 50,
width: 50,
child: Align(
alignment: Alignment.center,
child: widget.isnew != "1"
? Text(
widget.pos.toString(),
textAlign: TextAlign.center,
)
: const Text(
"new",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
)))),
],
),
Column(
children: [
SizedBox(
height: 50,
width: 50,
child: Image.network(
'${'http://www.example.com/${widget.element}'}.jpg'),
),
],
),
Column(
children: [
titles,
],
),
Column(
children: [
SizedBox(
height: 50,
width: 50,
child: TextButton(
onPressed: () async {
final url =
'${'http://www.example.com/${widget.element}'}.mp3';
await player.setUrl(url);
player.play();
},
child: Image.asset('assets/images/btn_play.png'),
),
),
],
),
Column(
children: [
SizedBox(
height: 50,
width: 50,
child: TextButton(
// ignore: avoid_print
onPressed: () =>
print('pressed button download!! ${widget.element}'),
child: Image.asset('assets/images/btn_download.png'),
),
),
],
),
],
)));
}
}
Future<SongList> fetchSong() async {
final response = await http
.get(Uri.parse('http://example.com'));
if (response.statusCode == 200) {
return SongList.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to Load Songs');
}
}
//snippet from class that instatiates
late Future<SongList> futureSong;
@override
void initState() {
super.initState();
futureSong = fetchSong();
}
//snippet from class that builds the list
FutureBuilder<SongList>(
future: futureSong,
builder: (context, AsyncSnapshot<SongList> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.songs.length,
itemBuilder: (context, index) {
if (snapshot.data!.songs[index].element.toString() !=
"null") {
return Songs(
element:
snapshot.data!.songs[index].element.toString(),
inter: snapshot.data!.songs[index].inter.toString(),
isnew: snapshot.data!.songs[index].isnew.toString(),
pos: snapshot.data!.songs[index].pos.toString(),
title: snapshot.data!.songs[index].title.toString());
} else {
return const SizedBox(height: 0);
}
});
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
}
CodePudding user response:
This might work:
void main() {
var data=[
{
"pos":"1",
"element":"37542",
"title":"Easy On Me",
"inter":"Adele",
"isnew":"0"
},
{
"pos":"66",
"element":"37183",
"title":"Send My Love",
"inter":"Adele",
"isnew":"0"
},
{
"pos":"80",
"element":"5000",
"title":"Enjoy the silence",
"inter":"Depeche Mode",
"isnew":"0"
},
{
"pos":"100",
"element":"6000",
"title":"In your room",
"inter":"Depeche Mode",
"isnew":"0"
}
];
var result = <String,List<Map<String,String>>>{};
for (var d in data) {
print(d);
var e={"element":d["element"]!, "title": d["title"]!};
var key=d["inter"]!;
if (result.containsKey(key)) {
result[key]!.add(e);
} else {
result[key]=[e];
}
}
print(result);
}
CodePudding user response:
You can achieve this by creating a subclass.
Interpret interpretFromJson(String st) => Interpret.fromJson(json.decode(st));
class Interpret{
Interpret({
required this.name,
required this.titles,
});
final String name;
final List<Title> titles;
factory Interpret.fromJson(Map<String, dynamic> json) => Title(
name: json["inter"],
titles: List<Title>.from(json.map((x) => Title.fromJson(x))),
);
}
class Title {
Title({
required this.name,
required this.element,
});
final String name;
final double element;
factory Title.fromJson(Map<String, dynamic> json) => Title(
name: json["name"],
element: json["element"],
);
Then you can just call it like.
InterpretFromJson(json);