Flutter: ChangeNotifierProvider doesn't work with my MVVM architecture - json

I have a complex JSON object and I already converted it to dart code using JSON to Dart plugin. I have created a View Model to call my API and update the provider. However, the provider doesn't seem to work.
The API response is successful but I get this error message ->
The following NoSuchMethodError was thrown building Builder: The getter 'replyStatus' was called on null. Receiver: null Tried calling: replyStatus
Can anyone help me to solve this issue?
Below is the code I have.
JSON to Dart Response
class UserProfile {
int replyStatus;
String replyDesc;
int debugStep;
bool hasData;
int actualDataSize;
List<ResultObjectSet> resultObjectSet;
dynamic token;
UserProfile(
{this.replyStatus,
this.replyDesc,
this.debugStep,
this.hasData,
this.actualDataSize,
this.resultObjectSet,
this.token});
UserProfile.fromJson(Map<String, dynamic> json) {
replyStatus = json['ReplyStatus'];
replyDesc = json['ReplyDesc'];
debugStep = json['DebugStep'];
hasData = json['HasData'];
actualDataSize = json['ActualDataSize'];
if (json['ResultObjectSet'] != null) {
// ignore: deprecated_member_use
resultObjectSet = new List<ResultObjectSet>();
json['ResultObjectSet'].forEach((v) {
resultObjectSet.add(new ResultObjectSet.fromJson(v));
});
}
token = json['Token'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ReplyStatus'] = this.replyStatus;
data['ReplyDesc'] = this.replyDesc;
data['DebugStep'] = this.debugStep;
data['HasData'] = this.hasData;
data['ActualDataSize'] = this.actualDataSize;
if (this.resultObjectSet != null) {
data['ResultObjectSet'] =
this.resultObjectSet.map((v) => v.toJson()).toList();
}
data['Token'] = this.token;
return data;
}
}
class ResultObjectSet {
String objectName;
ObjectSet objectSet;
ResultObjectSet({this.objectName, this.objectSet});
ResultObjectSet.fromJson(Map<String, dynamic> json) {
objectName = json['ObjectName'];
objectSet = json['ObjectSet'] != null
? new ObjectSet.fromJson(json['ObjectSet'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ObjectName'] = this.objectName;
if (this.objectSet != null) {
data['ObjectSet'] = this.objectSet.toJson();
}
return data;
}
}
class ObjectSet {
int userId;
String userName;
String regsterEmail;
String lastLogin;
double displayTimeZone;
int accountStatus;
int language;
List<UserCompany> userCompany;
MenuOption menuOption;
bool pnmDisableFlag;
ObjectSet(
{this.userId,
this.userName,
this.regsterEmail,
this.lastLogin,
this.displayTimeZone,
this.accountStatus,
this.language,
this.userCompany,
this.menuOption,
this.pnmDisableFlag});
ObjectSet.fromJson(Map<String, dynamic> json) {
userId = json['UserId'];
userName = json['UserName'];
regsterEmail = json['RegsterEmail'];
lastLogin = json['LastLogin'];
displayTimeZone = json['DisplayTimeZone'];
accountStatus = json['AccountStatus'];
language = json['Language'];
if (json['UserCompany'] != null) {
// ignore: deprecated_member_use
userCompany = new List<UserCompany>();
json['UserCompany'].forEach((v) {
userCompany.add(new UserCompany.fromJson(v));
});
}
menuOption = json['MenuOption'] != null
? new MenuOption.fromJson(json['MenuOption'])
: null;
pnmDisableFlag = json['PnmDisableFlag'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['UserId'] = this.userId;
data['UserName'] = this.userName;
data['RegsterEmail'] = this.regsterEmail;
data['LastLogin'] = this.lastLogin;
data['DisplayTimeZone'] = this.displayTimeZone;
data['AccountStatus'] = this.accountStatus;
data['Language'] = this.language;
if (this.userCompany != null) {
data['UserCompany'] = this.userCompany.map((v) => v.toJson()).toList();
}
if (this.menuOption != null) {
data['MenuOption'] = this.menuOption.toJson();
}
data['PnmDisableFlag'] = this.pnmDisableFlag;
return data;
}
}
class UserCompany {
int companyId;
String companyName;
int typeUserRoleId;
String typeUserRoleDesc;
int menuRights;
int reportRights;
ManagementCompanyRights managementCompanyRights;
ManagementCompanyRights managementUserRights;
ManagementCompanyRights managementUserRole;
ManagementCompanyRights managementFleetRights;
ManagementCompanyRights managementShipRights;
UserCompany(
{this.companyId,
this.companyName,
this.typeUserRoleId,
this.typeUserRoleDesc,
this.menuRights,
this.reportRights,
this.managementCompanyRights,
this.managementUserRights,
this.managementUserRole,
this.managementFleetRights,
this.managementShipRights});
UserCompany.fromJson(Map<String, dynamic> json) {
companyId = json['CompanyId'];
companyName = json['CompanyName'];
typeUserRoleId = json['TypeUserRoleId'];
typeUserRoleDesc = json['TypeUserRoleDesc'];
menuRights = json['MenuRights'];
reportRights = json['ReportRights'];
managementCompanyRights = json['ManagementCompanyRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementCompanyRights'])
: null;
managementUserRights = json['ManagementUserRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementUserRights'])
: null;
managementUserRole = json['ManagementUserRole'] != null
? new ManagementCompanyRights.fromJson(json['ManagementUserRole'])
: null;
managementFleetRights = json['ManagementFleetRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementFleetRights'])
: null;
managementShipRights = json['ManagementShipRights'] != null
? new ManagementCompanyRights.fromJson(json['ManagementShipRights'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['CompanyId'] = this.companyId;
data['CompanyName'] = this.companyName;
data['TypeUserRoleId'] = this.typeUserRoleId;
data['TypeUserRoleDesc'] = this.typeUserRoleDesc;
data['MenuRights'] = this.menuRights;
data['ReportRights'] = this.reportRights;
if (this.managementCompanyRights != null) {
data['ManagementCompanyRights'] = this.managementCompanyRights.toJson();
}
if (this.managementUserRights != null) {
data['ManagementUserRights'] = this.managementUserRights.toJson();
}
if (this.managementUserRole != null) {
data['ManagementUserRole'] = this.managementUserRole.toJson();
}
if (this.managementFleetRights != null) {
data['ManagementFleetRights'] = this.managementFleetRights.toJson();
}
if (this.managementShipRights != null) {
data['ManagementShipRights'] = this.managementShipRights.toJson();
}
return data;
}
}
class ManagementCompanyRights {
bool add;
bool edit;
bool delete;
bool fleetAssignment;
ManagementCompanyRights(
{this.add, this.edit, this.delete, this.fleetAssignment});
ManagementCompanyRights.fromJson(Map<String, dynamic> json) {
add = json['Add'];
edit = json['Edit'];
delete = json['Delete'];
fleetAssignment = json['FleetAssignment'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Add'] = this.add;
data['Edit'] = this.edit;
data['Delete'] = this.delete;
data['FleetAssignment'] = this.fleetAssignment;
return data;
}
}
class MenuOption {
bool dashBoard;
bool fuelCons;
bool bunkering;
bool aMS;
bool shaftPower;
bool kpiPerformance;
bool eOM;
bool route;
bool report;
bool management;
MenuOption(
{this.dashBoard,
this.fuelCons,
this.bunkering,
this.aMS,
this.shaftPower,
this.kpiPerformance,
this.eOM,
this.route,
this.report,
this.management});
MenuOption.fromJson(Map<String, dynamic> json) {
dashBoard = json['DashBoard'];
fuelCons = json['FuelCons'];
bunkering = json['Bunkering'];
aMS = json['AMS'];
shaftPower = json['ShaftPower'];
kpiPerformance = json['KpiPerformance'];
eOM = json['EOM'];
route = json['Route'];
report = json['Report'];
management = json['Management'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['DashBoard'] = this.dashBoard;
data['FuelCons'] = this.fuelCons;
data['Bunkering'] = this.bunkering;
data['AMS'] = this.aMS;
data['ShaftPower'] = this.shaftPower;
data['KpiPerformance'] = this.kpiPerformance;
data['EOM'] = this.eOM;
data['Route'] = this.route;
data['Report'] = this.report;
data['Management'] = this.management;
return data;
}
}
Main.Dart
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => UserVM(),
),
],
child: MaterialApp(
initialRoute: LoginScreen.id,
routes: {
LoginScreen.id: (context) => LoginScreen(),
SelectCompany.id: (context) => SelectCompany(),
},
),
);
}
}
My API class
class LoginScreenApi {
var dio = Dio();
Future<UserProfile> authenticateUser(
String email, String password, String token) async {
try {
String queryURL =
'$domainURL/User/LoginMobile?Email=$email&UserPassword=$password&MobileDeviceTokenId=$token';
Response response = await dio.get(queryURL);
print('login status: ${response.statusCode}');
if (response.statusCode == 200) {
UserProfile user = UserProfile.fromJson(response.data);
return user;
}
return null;
} catch (e) {
print(e);
return null;
}
}
}
My VM class
class UserVM extends ChangeNotifier {
UserProfile user;
UserVM({this.user});
/// Call Login API
Future<void> authenticateUser(
String email, String password, String token) async {
final results =
await LoginScreenApi().authenticateUser(email, password, token);
/// if login successfully, save the USER result and route to select company page
if (results != null) {
this.user = results;
notifyListeners();
Navigator.pushNamed(navigatorKey.currentContext, SelectCompany.id);
} else {
showDialog(
context: navigatorKey.currentContext,
builder: (BuildContext context) {
return PopUpDialog(
text: 'Wrong User ID or Password!',
);
});
}
}
}
The screen that I display the data from my provider
class _SelectCompanyState extends State<SelectCompany> {
#override
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Text(
'${Provider.of<UserVM>(context, listen: false).replyStatus}',
style: TextStyle(color: Colors.black),
),
),
);
}
}
The Widget that call the Authenticate method at my login screen
Widget _loginButton() {
// ignore: deprecated_member_use
return RaisedButton(
onPressed: () async {
await user.authenticateUser(email, password, deviceToken);
setState(() {
showSpinner = true;
});
},
color: Colors.black,
child: Text(
'${userLanguage == 'chinese' ? '登入' : 'Login'}',
style:
TextStyle(fontSize: 15, color: Colors.yellow, fontFamily: 'Roboto'),
),
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.lightBlueAccent)),
);
}

The following line loads an instance of your UserVM.
final userVM = Provider<UserVM>.of(context,listen:false);
Your UserVM class doesn't have a property called replyStatus, it's your UserProfile class that does. So call it like this:
final replyStatus = userVM.user.replyStatus;
Note: Your user can also be null since you're not passing it while creating the UserVM(). Neither are you calling the authenticate method for user to be updated with results. If you're handling that somewhere else in your code that's fine else you need to check user for null as well before calling:
final replyStatus;
If(userVM.user! = null) replyStatus = userVM.user.replyStatus;
else //<-- some alternative here

Related

Flutter/Dart: JSON parsing

Is it possible to get a list from json without looping the jsonResponse?
In the sample below, i want to get list of language
targetList = ["Pascal", "Python","SQL"]
{
"eBooks":[
{
"language":"Pascal",
"edition":"third"
},
{
"language":"Python",
"edition":"four"
},
{
"language":"SQL",
"edition":"second"
}
]
}
void main() {
String json = "{\"eBooks\":[{\"language\":\"Pascal\",\"edition\":\"third\"},{\"language\":\"Python\",\"edition\":\"four\"},{\"language\":\"SQL\",\"edition\":\"second\"}]}";
JsonData result = JsonData.fromJson(jsonDecode(json));
List<String> targetList = [];
for(var book in result.eBooks!) {
targetList.add(book.language!);
}
print(targetList); // [Pascal, Python, SQL]
}
Json Object:
class JsonData {
List<EBooks>? _eBooks;
List<EBooks>? get eBooks => _eBooks;
JsonData({List<EBooks>? eBooks}) {
_eBooks = eBooks;
}
JsonData.fromJson(dynamic json) {
if (json["eBooks"] != null) {
_eBooks = [];
json["eBooks"].forEach((v) {
_eBooks?.add(EBooks.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
if (_eBooks != null) {
map["eBooks"] = _eBooks?.map((v) => v.toJson()).toList();
}
return map;
}
}
class EBooks {
String? _language;
String? _edition;
String? get language => _language;
String? get edition => _edition;
EBooks({String? language, String? edition}) {
_language = language;
_edition = edition;
}
EBooks.fromJson(dynamic json) {
_language = json["language"];
_edition = json["edition"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["language"] = _language;
map["edition"] = _edition;
return map;
}
}
Have a look at the example below
void main() {
var map = {
"eBooks": [
{"language": "Pascal", "edition": "third"},
{"language": "Python", "edition": "four"},
{"language": "SQL", "edition": "second"}
]
};
var lst = map["eBooks"].map((e) => e["language"]).toList();
print(lst.length);
lst.forEach((l) {
print(l);
});
}
First you need to create a model class. Then we see a second value in which the other variables are kept. Then you can access the list in it by creating an object from this class. You can translate your model to JSON to Dart language through these sites. jsontodart jsontodart2
class TargetList {
List<EBooks> eBooks;
TargetList({this.eBooks});
TargetList.fromJson(Map<String, dynamic> json) {
if (json['eBooks'] != null) {
eBooks = new List<EBooks>();
json['eBooks'].forEach((v) {
eBooks.add(new EBooks.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.eBooks != null) {
data['eBooks'] = this.eBooks.map((v) => v.toJson()).toList();
}
return data;
}
}
class EBooks {
String language;
String edition;
EBooks({this.language, this.edition});
EBooks.fromJson(Map<String, dynamic> json) {
language = json['language'];
edition = json['edition'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['language'] = this.language;
data['edition'] = this.edition;
return data;
}
}

Error: type 'String' is not a subtype of type 'List<dynamic>'

I want to fetch dat form some API and parse its data to model.
MyModel:
class SetupIdeaModel {
String id;
String userId;
String typeIdea = "Implemented Idea";
String category; //Or Industry
String experienceYear;
String experienceMonth;
String ideaHeadline;
String ideaText;
Map timeline = {
"timelineType": "date",
"details": null,
};
List documents = [];
Map uploadVideo;
String location;
String estimatedPeople;
Map whitePaper;
bool needServiceProvider = false;
bool needInvestor = true;
}
}
and I fetch data from the API with the getIdeaList method:
getIdeaList method
Future getIdeaList(String token) async {
Response response = await APIRequest().get(
myUrl: "$baseUrl/innovator/idea/list",
token: token,
);
//Parsing ideaList to SetupIdeaModel
ideas = List();
try {
(response.data as List).forEach((element) {
SetupIdeaModel idea = new SetupIdeaModel();
var months = int.parse(element["industryExperienceInMonth"]);
var year = (months / 12).floor();
var remainderMonths = months % 12;
print("$year year and $remainderMonths months");
idea.id = element["_id"];
idea.userId = element["userId"];
idea.typeIdea = element["ideaType"];
idea.category = element["industry"];
idea.experienceYear = year.toString();
idea.experienceMonth = remainderMonths.toString();
idea.ideaHeadline = element["headline"];
idea.ideaText = element["idea"];
idea.estimatedPeople = element["estimatedPeople"].toString();
print("Documents ${element["uploadDocuments"]}");
idea.location = element["targetAudience"];
idea.documents = element["uploadDocuments"];
// idea.timeline = element["timeline"];
// idea.uploadVideo = element["uploadVideo"];
ideas.add(idea);
});
} catch (e) {
print("Error: $e");
}
print("ideas $ideas");
notifyListeners();
}
Everything is OK but When I add one of these line:
idea.documents = element["uploadDocuments"];
idea.timeline = element["timeline"];
idea.uploadVideo = element["uploadVideo"];
I have got the error.
The data comes for the API is like this:
[
{
"industryExperienceInMonth":30,
"estimatedPeople":200,
"needServiceProvider":true,
"needInvestor":true,
"_id":5fcc681fc5b4260011810112,
"userId":5fb6650eacc60d0011910a9b,
"ideaType":"Implemented Idea",
"industry":"Technalogy",
"headline":"IDea headline",
"idea":"This is aobut your idea",
"timeline":{
"timelineType":"date",
"details":{
"date":Dec 6,
2020
}
},
"uploadDocuments":[
{
"_id":5fcc6804c5b4260011810110,
"uriPath":"https"://webfume-onionai.s3.amazonaws.com/guest/public/document/741333-beats_by_dre-wallpaper-1366x768.jpg
}
],
"uploadVideo":{
"_id":5fcc681ac5b4260011810111,
"uriPath":"https"://webfume-onionai.s3.amazonaws.com/guest/public/video/588700-beats_by_dre-wallpaper-1366x768.jpg
},
"targetAudience":"heart",
"__v":0
}
]
I'm using Dio package.
The documents in the model is a list and the uploadDocuments the come form API is a list too. But Why I got this error.
Your JSON data has some syntax errors that's why it's not working. All the UIDs and URLs should be in string format and you should Serializing JSON inside model classes. see also
I have fix some error in your code and did some improvement :
Future getIdeaList(String token) async {
List<SetupIdeaModel> setupIdeaModel = List();
try {
Response response = await APIRequest().get(
myUrl: "$baseUrl/innovator/idea/list",
token: token,
);
if (response.statusCode == 200) {
List<SetupIdeaModel> apiData = (json.decode(utf8.decode(response.data)) as List)
.map((data) => new SetupIdeaModel.fromJson(data))
.toList();
setupIdeaModel.addAll(apiData);
}
} catch (e) {
print("Error: $e");
}
}
This is the model class :
class SetupIdeaModel {
int industryExperienceInMonth;
int estimatedPeople;
bool needServiceProvider;
bool needInvestor;
String sId;
String userId;
String ideaType;
String industry;
String headline;
String idea;
Timeline timeline;
List<UploadDocuments> uploadDocuments;
UploadDocuments uploadVideo;
String targetAudience;
int iV;
SetupIdeaModel(
{this.industryExperienceInMonth,
this.estimatedPeople,
this.needServiceProvider,
this.needInvestor,
this.sId,
this.userId,
this.ideaType,
this.industry,
this.headline,
this.idea,
this.timeline,
this.uploadDocuments,
this.uploadVideo,
this.targetAudience,
this.iV});
SetupIdeaModel.fromJson(Map<String, dynamic> json) {
industryExperienceInMonth = json['industryExperienceInMonth'];
estimatedPeople = json['estimatedPeople'];
needServiceProvider = json['needServiceProvider'];
needInvestor = json['needInvestor'];
sId = json['_id'];
userId = json['userId'];
ideaType = json['ideaType'];
industry = json['industry'];
headline = json['headline'];
idea = json['idea'];
timeline = json['timeline'] != null
? new Timeline.fromJson(json['timeline'])
: null;
if (json['uploadDocuments'] != null) {
uploadDocuments = new List<UploadDocuments>();
json['uploadDocuments'].forEach((v) {
uploadDocuments.add(new UploadDocuments.fromJson(v));
});
}
uploadVideo = json['uploadVideo'] != null
? new UploadDocuments.fromJson(json['uploadVideo'])
: null;
targetAudience = json['targetAudience'];
iV = json['__v'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['industryExperienceInMonth'] = this.industryExperienceInMonth;
data['estimatedPeople'] = this.estimatedPeople;
data['needServiceProvider'] = this.needServiceProvider;
data['needInvestor'] = this.needInvestor;
data['_id'] = this.sId;
data['userId'] = this.userId;
data['ideaType'] = this.ideaType;
data['industry'] = this.industry;
data['headline'] = this.headline;
data['idea'] = this.idea;
if (this.timeline != null) {
data['timeline'] = this.timeline.toJson();
}
if (this.uploadDocuments != null) {
data['uploadDocuments'] =
this.uploadDocuments.map((v) => v.toJson()).toList();
}
if (this.uploadVideo != null) {
data['uploadVideo'] = this.uploadVideo.toJson();
}
data['targetAudience'] = this.targetAudience;
data['__v'] = this.iV;
return data;
}
}
class Timeline {
String timelineType;
Details details;
Timeline({this.timelineType, this.details});
Timeline.fromJson(Map<String, dynamic> json) {
timelineType = json['timelineType'];
details =
json['details'] != null ? new Details.fromJson(json['details']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['timelineType'] = this.timelineType;
if (this.details != null) {
data['details'] = this.details.toJson();
}
return data;
}
}
class Details {
String date;
Details({this.date});
Details.fromJson(Map<String, dynamic> json) {
date = json['date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['date'] = this.date;
return data;
}
}
class UploadDocuments {
String sId;
String uriPath;
UploadDocuments({this.sId, this.uriPath});
UploadDocuments.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
uriPath = json['uriPath'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['_id'] = this.sId;
data['uriPath'] = this.uriPath;
return data;
}
}

how to filx Unexpected character (at char 1) in flutter

hy we have a radio server with the followoing json file
{
"icestats":{
"admin":"icemaster#localhost",
"host":"online.localhost.be",
"location":"Earth",
"server_id":"Icecast 2.4.4",
"server_start":"Sun, 30 Aug 2020 10:50:52 +0200",
"server_start_iso8601":"2020-08-30T10:50:52+0200",
"source":[
{
"audio_info":"ice-samplerate=44100;ice-bitrate=320;ice-channels=2",
"bitrate":320,
"genre":"oldies",
"ice-bitrate":320,
"ice-channels":2,
"ice-samplerate":44100,
"listener_peak":0,
"listeners":0,
"listenurl":"http://127.0.0.1:8000/mp3_320",
"server_description":"Very Oldies!",
"server_name":"loclahost",
"server_type":"audio/mpeg",
"server_url":"https://127.0.0.1:8000",
"stream_start":"Sun, 30 Aug 2020 13:45:16 +0200",
"stream_start_iso8601":"2020-08-30T13:45:16+0200",
"title":"1951: Four Knights - I Love The Sunshine Of Your Smile",
"dummy":null
},
{
"audio_bitrate":320000,
"audio_channels":2,
"audio_info":"ice-samplerate=44100;ice-bitrate=320;ice-channels=2",
"audio_samplerate":44100,
"bitrate":320,
"genre":"oldies",
"ice-bitrate":320,
"ice-channels":2,
"ice-samplerate":44100,
"listener_peak":0,
"listeners":0,
"listenurl":"http://127.0.0.1:8000/ogg_320",
"server_description":"Very Oldies!",
"server_name":"localhost",
"server_type":"application/ogg",
"server_url":"https://127.0.0.1:8000",
"stream_start":"Sun, 30 Aug 2020 13:45:16 +0200",
"stream_start_iso8601":"2020-08-30T13:45:16+0200",
"subtype":"Vorbis",
"dummy":null
}
]
}
}
if io parse this with this model i get the error 'unexpected charcater at 1'
class Autogenerated {
Icestats icestats;
Autogenerated({this.icestats});
Autogenerated.fromJson(Map<String, dynamic> json) {
icestats = json['icestats'] != null
? new Icestats.fromJson(json['icestats'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.icestats != null) {
data['icestats'] = this.icestats.toJson();
}
return data;
}
}
class Icestats {
String admin;
String host;
String location;
String serverId;
String serverStart;
String serverStartIso8601;
List<Source> source;
Icestats(
{this.admin,
this.host,
this.location,
this.serverId,
this.serverStart,
this.serverStartIso8601,
this.source});
Icestats.fromJson(Map<String, dynamic> json) {
admin = json['admin'];
host = json['host'];
location = json['location'];
serverId = json['server_id'];
serverStart = json['server_start'];
serverStartIso8601 = json['server_start_iso8601'];
if (json['source'] != null) {
source = new List<Source>();
json['source'].forEach((v) {
source.add(new Source.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['admin'] = this.admin;
data['host'] = this.host;
data['location'] = this.location;
data['server_id'] = this.serverId;
data['server_start'] = this.serverStart;
data['server_start_iso8601'] = this.serverStartIso8601;
if (this.source != null) {
data['source'] = this.source.map((v) => v.toJson()).toList();
}
return data;
}
}
class Source {
String audioInfo;
int bitrate;
String genre;
int iceBitrate;
int iceChannels;
int iceSamplerate;
int listenerPeak;
int listeners;
String listenurl;
String serverDescription;
String serverName;
String serverType;
String serverUrl;
String streamStart;
String streamStartIso8601;
String title;
Null dummy;
int audioBitrate;
int audioChannels;
int audioSamplerate;
String subtype;
Source(
{this.audioInfo,
this.bitrate,
this.genre,
this.iceBitrate,
this.iceChannels,
this.iceSamplerate,
this.listenerPeak,
this.listeners,
this.listenurl,
this.serverDescription,
this.serverName,
this.serverType,
this.serverUrl,
this.streamStart,
this.streamStartIso8601,
this.title,
this.dummy,
this.audioBitrate,
this.audioChannels,
this.audioSamplerate,
this.subtype});
Source.fromJson(Map<String, dynamic> json) {
audioInfo = json['audio_info'];
bitrate = json['bitrate'];
genre = json['genre'];
iceBitrate = json['ice-bitrate'];
iceChannels = json['ice-channels'];
iceSamplerate = json['ice-samplerate'];
listenerPeak = json['listener_peak'];
listeners = json['listeners'];
listenurl = json['listenurl'];
serverDescription = json['server_description'];
serverName = json['server_name'];
serverType = json['server_type'];
serverUrl = json['server_url'];
streamStart = json['stream_start'];
streamStartIso8601 = json['stream_start_iso8601'];
title = json['title'];
dummy = json['dummy'];
audioBitrate = json['audio_bitrate'];
audioChannels = json['audio_channels'];
audioSamplerate = json['audio_samplerate'];
subtype = json['subtype'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['audio_info'] = this.audioInfo;
data['bitrate'] = this.bitrate;
data['genre'] = this.genre;
data['ice-bitrate'] = this.iceBitrate;
data['ice-channels'] = this.iceChannels;
data['ice-samplerate'] = this.iceSamplerate;
data['listener_peak'] = this.listenerPeak;
data['listeners'] = this.listeners;
data['listenurl'] = this.listenurl;
data['server_description'] = this.serverDescription;
data['server_name'] = this.serverName;
data['server_type'] = this.serverType;
data['server_url'] = this.serverUrl;
data['stream_start'] = this.streamStart;
data['stream_start_iso8601'] = this.streamStartIso8601;
data['title'] = this.title;
data['dummy'] = this.dummy;
data['audio_bitrate'] = this.audioBitrate;
data['audio_channels'] = this.audioChannels;
data['audio_samplerate'] = this.audioSamplerate;
data['subtype'] = this.subtype;
return data;
}
}
the code i have used i pretty simple this is the code i have used.
if i parse the same code with a simple xml structure this works but with the icecast parsing this does not succeed.
please advice me
var JsonData = 'http://127.0.0.1:8000/status-json.xsl';
var parsedJson = json.decode(JsonData);
var title = Source.fromJson(parsedJson);
is the json formatting of the icecast server incorrect ? it starts with a {
update 1
class User {
String title;
User(Map<String, dynamic> data){
title = data['title'];
}
}
Future<Source> fetchData() async{
var jsonData = 'http://online.doobeedoo.be:8000/status-json.xsl';
final response =
await http.get(jsonData); //wacht to de data is ontvangen (200)
if(response.statusCode == 200)
{
var parsedJson = json.decode(response.body); //parsen van response
var user = User(parsedJson);
return('${user.title}'); //error here (A value of type 'String' can't be returned from function 'fetchData' because it has a return type of 'Future<Source>'.)
}
else
{
throw Exception('Failed to load status.json response file');
}
}
Use the http package to make a request to your server and retrieve a response. Then parse the JSON the way your currently have it. You're currently parsing a String URL. Not a JSON.
import 'package:http/http.dart' as http;
var url = 'http://127.0.0.1:8000/status-json.xsl';
var response = await http.get(url);//Actually get the data at the URL
var parsedJson = json.decode(response.body);//Parse the response
var title = Source.fromJson(parsedJson);

get value from nested json array and check if it is empty or not in flutter

My json array looks like:
[
{
"sub_categories": [],
"category_id": "82",
"catgory_name": "Andrew Murray 1 Month",
"parent_cat_id": "1"
},
{
"sub_categories": [
{
"category_id": "177",
"catgory_name": "2 Samuel",
"parent_cat_id": "167"
}
],
"category_id": "167",
"catgory_name": "The Bible ASV",
"parent_cat_id": "1"
},
]
First i want to display "catgory_name" in listview and if that catgory_name has sub_categories array than i need to display it in another list , so how can i achieve this.
i get all catgory_name by following code:
class CategoryModel {
final String name;
final List<SubCategoryModel> SubCategory;
CategoryModel({
this.name,
this.SubCategory,
});
factory CategoryModel.fromJson(Map<String, dynamic> json) {
return new CategoryModel(
name: json['catgory_name'].toString(),
SubCategory: parsesub_categories(json['sub_categories']),
// SubCategory:(json['sub_categories'] as List).map((map) => map).toList(),
);
}
static List<SubCategoryModel> parsesub_categories(cateJson) {
List<SubCategoryModel> catlist = new List<SubCategoryModel>.from(cateJson);
return catlist;
}
but sub_categories i could not get that array .
You can create data model as below:
class CategoryModel {
List<SubCateogryModel> subCategories;
String categoryId;
String catgoryName;
String parentCatId;
CategoryModel(
{this.subCategories,
this.categoryId,
this.catgoryName,
this.parentCatId});
CategoryModel.fromJson(Map<String, dynamic> json) {
if (json['sub_categories'] != null) {
subCategories = new List<SubCateogryModel>();
json['sub_categories'].forEach((v) {
subCategories.add(new SubCateogryModel.fromJson(v));
});
}
categoryId = json['category_id'];
catgoryName = json['catgory_name'];
parentCatId = json['parent_cat_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.subCategories != null) {
data['sub_categories'] =
this.subCategories.map((v) => v.toJson()).toList();
}
data['category_id'] = this.categoryId;
data['catgory_name'] = this.catgoryName;
data['parent_cat_id'] = this.parentCatId;
return data;
}
}
class SubCateogryModel {
String categoryId;
String catgoryName;
String parentCatId;
SubCateogryModel({this.categoryId, this.catgoryName, this.parentCatId});
SubCateogryModel.fromJson(Map<String, dynamic> json) {
categoryId = json['category_id'];
catgoryName = json['catgory_name'];
parentCatId = json['parent_cat_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['category_id'] = this.categoryId;
data['catgory_name'] = this.catgoryName;
data['parent_cat_id'] = this.parentCatId;
return data;
}
}
Now, you have to parse your json array into Data model array
List<CategoryModel> categoryList = [];
jsonArray.forEach((val){
categoryList.add(CategoryModel.fromJson(val));
});
Now, the UI code,
ListView.builder(
itemBuilder: (context, index) {
return ListTile(
title: Text(categoryList[index].catgoryName),
subtitle: categoryList[index].subCategories.isNotEmpty
? Column(
children: List.generate(
categoryList[index].subCategories.length, (position) {
String subCategory = categoryList[index]
.subCategories[position]
.catgoryName;
return Text(subCategory);
}),
)
: SizedBox(),
);
},
itemCount: categoryList.length,
)
You can use QuickType.io to generate dart classes (PODOs) for json.
import 'dart:convert';
List<CategoryModel> categoryModelFromJson(String str) => List<CategoryModel>.from(json.decode(str).map((x) => CategoryModel.fromJson(x)));
String categoryModelToJson(List<CategoryModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class CategoryModel {
List<CategoryModel> subCategories;
String categoryId;
String catgoryName;
String parentCatId;
CategoryModel({
this.subCategories,
this.categoryId,
this.catgoryName,
this.parentCatId,
});
factory CategoryModel.fromJson(Map<String, dynamic> json) => CategoryModel(
subCategories: json["sub_categories"] == null ? null : List<CategoryModel>.from(json["sub_categories"].map((x) => CategoryModel.fromJson(x))),
categoryId: json["category_id"],
catgoryName: json["catgory_name"],
parentCatId: json["parent_cat_id"],
);
Map<String, dynamic> toJson() => {
"sub_categories": subCategories == null ? null : List<dynamic>.from(subCategories.map((x) => x.toJson())),
"category_id": categoryId,
"catgory_name": catgoryName,
"parent_cat_id": parentCatId,
};
}

Adding data to a json file in dart

I have a Json file having some user data as an array , I am able to read those data in my flutter project , But what I wanna do is to add some other user from the data I receive from the textfield in my flutter app.
Can anyone tell me how to do that ? Thanks in advance.
My Json file looks something like this.
{
"users": [
{
"id": 1,
"username": "steve",
"password": "captainamerica"
}
]
}
and I have to add another user with id - 2, username - tony, and password - ironman.
I have tried showing you how to map the JSON to OBJECT and then add a new user to the users object and then to JSON again.
Here's the complete code:
If you have any doubts, please ask:
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
UsersPodo _usersPodo; // Users object to store users from json
// A function that converts a response body into a UsersPodo
UsersPodo parseJson(String responseBody) {
final parsed = json.decode(responseBody);
return UsersPodo.fromJson(parsed);
}
class Demo extends StatefulWidget {
#override
_Demo createState() => _Demo();
}
class _Demo extends State<Demo> {
final String localJson = '''
{
"users": [
{
"id": 1,
"username": "steve",
"password": "captainamerica"
}
]
}'''; // local json string
Future<UsersPodo> fetchJSON() async {
return compute(parseJson, localJson);
}
Widget body() {
return FutureBuilder<UsersPodo>(
future: fetchJSON(),
builder: (context, snapshot) {
return snapshot.hasError
? Center(child: Text(snapshot.error.toString()))
: snapshot.hasData
? _buildBody(usersList: snapshot.data)
: Center(child: Text("Loading"));
},
);
}
Widget _buildBody({UsersPodo usersList}) {
_usersPodo = usersList;
_usersPodo.users.add(new Users(id: 1, username: "omishah", password: "somepassword")); // add new user to users array
return Text(_usersPodo.users[1].toJson().toString()); // just for the demo output
// use _usersPodo.toJson() to convert the users object to json
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xfff3f3f3),
appBar: AppBar(backgroundColor: Colors.red[900], title: Text("DEMO")),
body: body());
}
}
// PODO Object class for the JSON mapping
class UsersPodo {
List<Users> users;
UsersPodo({this.users});
UsersPodo.fromJson(Map<String, dynamic> json) {
if (json['users'] != null) {
users = new List<Users>();
json['users'].forEach((v) {
users.add(new Users.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.users != null) {
data['users'] = this.users.map((v) => v.toJson()).toList();
}
return data;
}
}
class Users {
int id;
String username;
String password;
Users({this.id, this.username, this.password});
Users.fromJson(Map<String, dynamic> json) {
id = json['id'];
username = json['username'];
password = json['password'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['username'] = this.username;
data['password'] = this.password;
return data;
}
}