Reputation: 65
Here is the json string that I get by http request. The aim is to display subjects according to the current weekday.
{
"first_name": "First Name",
"batch_name": "Batch 1",
"enrolled_subjects": [
"Subject 4",
"Subject 5"
],
"batch_timetable": {
"Mon": {
"Subject 4": [
"6:00 PM - 7:00 PM"
],
"Subject 5": [
"5:00 PM - 6:00 PM",
"7:00 PM - 8:00 PM"
],
"Subject 6": [
"8:00 PM - 9:00 PM"
]
},
"Tue": {
"Subject 4": [
"6:00 PM - 7:00 PM"
],
"Subject 5": [
"7:00 PM - 8:00 PM"
],
"Subject 6": [
"8:00 PM - 9:00 PM"
]
}, ...so on upto "Sun"
}
}
How to set Model Class for this json string?
I tried this Model Class but it gives this error : type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, List<dynamic>>'
I also tried Model Class by quicktype, but I think that won't work in this case.
class HomePageModel {
HomePageModel({
this.firstName,
this.batchName,
this.subjects,
this.timetable,
});
String firstName;
String batchName;
List<String> subjects;
Map timetable;
factory HomePageModel.fromJson(Map<String, dynamic> json) => HomePageModel(
firstName: json["first_name"],
batchName: json["batch_name"],
subjects: List<String>.from(json["subjects"].map((x) => x)),
timetable: Map.from(json["timetable"])
.map((key, value) => MapEntry(key, value)),
);
Map<String, dynamic> toJson() => {
"first_name": firstName,
"batch_name": batchName,
"subjects": List<dynamic>.from(subjects.map((x) => x)),
"timetable":
Map.from(timetable.map((key, value) => MapEntry(key, value))),
};
}
I am using FutureBuilder to display this data into UI. Any help would be appreciated.
Upvotes: 3
Views: 441
Reputation: 3777
So Far from the json you provided I have created and example for you in the listview format just check it out.
following is the json you provided:
{
"first_name": "First Name",
"batch_name": "Batch 1",
"enrolled_subjects": [
"Subject 4",
"Subject 5"
],
"batch_timetable": {
"Mon": {
"Subject 4": [
"6:00 PM - 7:00 PM"
],
"Subject 5": [
"5:00 PM - 6:00 PM",
"7:00 PM - 8:00 PM"
],
"Subject 6": [
"8:00 PM - 9:00 PM"
]
},
"Tue": {
"Subject 4": [
"6:00 PM - 7:00 PM"
],
"Subject 5": [
"7:00 PM - 8:00 PM"
],
"Subject 6": [
"8:00 PM - 9:00 PM"
]
}
}
}
Based on the json I have created a ui
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isLoading = false;
List<Timings> timingsList = List();
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
@override
void initState() {
super.initState();
dataLoadFunction();
}
dataLoadFunction() async {
setState(() {
_isLoading = true;
});
String jsonString = await loadFromAssets();
Map newStringMap = json.decode(jsonString);
//print(newStringMap['batch_timetable']);
newStringMap['batch_timetable'].forEach((key, value) {
List<Subjects> subjectsList = List();
print(key);
// print(value);
value.forEach((key, value) {
print(key);
print(value);
List<dynamic> timingValue = List();
timingValue.add(value);
Subjects subjects = Subjects(subjectName: key, timings: timingValue);
subjectsList.add(subjects);
});
Timings sampleObject = Timings(
day: key,
subjectList: subjectsList,
);
timingsList.add(sampleObject);
});
print(timingsList.length);
setState(() {
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: _isLoading
? CircularProgressIndicator()
: ListView.builder(
itemCount: timingsList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top:10,left:15),
child: Row(
children: <Widget>[
Text('Day :'),
Text(timingsList[index].day),
],
),
),
Divider(color: Colors.grey,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(' Day wise Subjects are :'),
ListView.builder(
itemCount: timingsList[index].subjectList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int i) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(timingsList[index]
.subjectList[i]
.subjectName),
for (int j = 0;
j <
timingsList[index]
.subjectList[i]
.timings
.length;
j++)
Text(timingsList[index]
.subjectList[i]
.timings[j]
.toString()),
],
);
},
)
],
)
],
),
);
},
),
),
);
}
}
class Timings {
final String day;
final List<Subjects> subjectList;
Timings({
this.day,
this.subjectList,
});
}
class Subjects {
final String subjectName;
final List<dynamic> timings;
Subjects({this.subjectName, this.timings});
}
I have just added the data, you can decorate it based on your desired ui:
What have I achieved in this code
1) Data will be fetched dynamically so that even if the json changes it will adapt accordingly.
2) Added it in the list view format ,you can do as you want.
Provided the sample ui that I have made
Let Me know if it works.
Upvotes: 2
Reputation: 795
for rest method :
import 'package:http/http.dart' as http;
Future<HomePageModel> restSample() async {
var response = await http.get('your URL');
var jsonResponse = json.decode(response.body);
HomePageModel homePageModel = HomePageModel.fromJson(jsonResponse);
return homePageModel;
}
for call timetable parameters:
homePageModel.batchTimetable.mon;
Upvotes: 0
Reputation: 795
use this:
class HomePageModel {
String firstName;
String batchName;
List<String> enrolledSubjects;
BatchTimetable batchTimetable;
HomePageModel(
{this.firstName,
this.batchName,
this.enrolledSubjects,
this.batchTimetable});
HomePageModel.fromJson(Map<String, dynamic> json) {
firstName = json['first_name'];
batchName = json['batch_name'];
enrolledSubjects = json['enrolled_subjects'].cast<String>();
batchTimetable = json['batch_timetable'] != null
? new BatchTimetable.fromJson(json['batch_timetable'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['first_name'] = this.firstName;
data['batch_name'] = this.batchName;
data['enrolled_subjects'] = this.enrolledSubjects;
if (this.batchTimetable != null) {
data['batch_timetable'] = this.batchTimetable.toJson();
}
return data;
}
}
class BatchTimetable {
Mon mon;
Mon tue;
BatchTimetable({this.mon, this.tue});
BatchTimetable.fromJson(Map<String, dynamic> json) {
mon = json['Mon'] != null ? new Mon.fromJson(json['Mon']) : null;
tue = json['Tue'] != null ? new Mon.fromJson(json['Tue']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.mon != null) {
data['Mon'] = this.mon.toJson();
}
if (this.tue != null) {
data['Tue'] = this.tue.toJson();
}
return data;
}
}
class Mon {
List<String> subject4;
List<String> subject5;
List<String> subject6;
Mon({this.subject4, this.subject5, this.subject6});
Mon.fromJson(Map<String, dynamic> json) {
subject4 = json['Subject 4'].cast<String>();
subject5 = json['Subject 5'].cast<String>();
subject6 = json['Subject 6'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Subject 4'] = this.subject4;
data['Subject 5'] = this.subject5;
data['Subject 6'] = this.subject6;
return data;
}
}
Upvotes: 0