decode stored json result string in shared preferences - json

When the app launch it triggers an API call and in my case, I want to store the response data for later use, so I used shared preferences for that and stored response data as a string. now I want to properly decode the data to use, from the stored string from shared preferences.
here is how I covert the data to string,
SharedPreferences prefs = await SharedPreferences.getInstance();
Response response = await _dio.post(
_baseUrl,
data: {"index": indexNum, "password": password},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
if (response.statusCode == 200) {
var result = response.data;
//convert result data to string
var resultData = Result.encode(result);
// store the resultData in shared_preferences
prefs.setString('results', resultData);
}
encode method,
class Result {
Result({
required this.table,
required this.data,
});
String table;
List<Data> data;
factory Result.fromJson(Map<String, dynamic> json) => Result(
table: json["table"],
data: List<Data>.from(json["data"].map((x) => Data.fromJson(x))),
);
//encode method
static String encode(List<dynamic> results) => json.encode(
results.map((result) => result.toString()).toList(),
);
}
here is my approach to decode data from string,
getData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? resultData = prefs.getString('results');
List<dynamic> decodedJson = jsonDecode(resultData!);
print(decodedJson);
}
resultData string,
resultData string after decode,
I am new to flutter and what I want is the proper way to decode this data from models. Below are my model classes.
import 'dart:convert';
class Result {
Result({
required this.table,
required this.data,
});
String table;
List<Data> data;
factory Result.fromJson(Map<String, dynamic> json) => Result(
table: json["table"],
data: List<Data>.from(json["data"].map((x) => Data.fromJson(x))),
);
static String encode(List<dynamic> results) => json.encode(
results.map((result) => result.toString()).toList(),
);
}
class Data {
Data({
required this.subjectName,
required this.year,
required this.credits,
required this.sOrder,
required this.result,
required this.onlineAssignmentResult,
});
String subjectName;
String year;
String credits;
String sOrder;
String result;
String onlineAssignmentResult;
factory Data.fromJson(json) => Data(
subjectName: json["subject_name"],
year: json["year"],
credits: json["credits"],
sOrder: json["s_order"],
result: json["result"],
onlineAssignmentResult: json["online_assignment_result"],
);
}
Appreciate your time and help.

Your JSON is in the wrong syntax for Flutter to decode with jsonDecode()
All strings and variable names need to be enclosed in " or '
I.e. {subject_name: should be {"subject_name":

Related

nhandled Exception: NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'call'

I am facing an issue when data is fetched from the api and is not mapped into the model and the following error is thrown I have also posted the BodyModel class which contains the fromJson function:
Future<BodyModel> fetchJson(http.Client client, String? id) async {
final response = await client.get(
Uri.parse(uri2),
);
if (response.statusCode == 200) {
String jsonData = response.body;
print(response.body);
//print(jsonEncode(response.body));
BodyModel alpha = responseJSON(jsonData);
//print(alpha.toSet());
//bravo = alpha;
return alpha;
} else {
throw Exception('We were not able to successfully download the json data.');
}
}
BodyModel responseJSON(String response) {
final parse = jsonDecode(response);
print(parse.toString());
final resp = parse<BodyModel>((json) => BodyModel.fromJson(json));
print(resp);
return resp;
}
import 'package:flutter/material.dart';
class BodyModel {
String body;
String title;
BodyModel({
required this.body,
required this.title,
});
factory BodyModel.fromJson(Map<String, dynamic> jsonData) {
return BodyModel(
body: jsonData['body'].toString(),
title: jsonData['title'].toString(),
);
}
}
You are calling parse<BodyModel>(...).
It's not clear what you think that's supposed to do, but parse is a variable containing a Map<String, dynamic>, not a generic function.
It has type dynamic, so you won't get any warnings when misusing it.
Consider declaring parse as
Map<String, dynamic> parse = jsonDecode(response);
so it has the correct type.
From the return type of responseJSON, my guess is that you want to do:
final resp = BodyModel.fromJson(parse);

Json Parsing in Flutter: List<dynamic > is not a subtype of type 'Map<String,dynamic>'

First of all, I am extremely new to working with HTTP Requests and stuff.
I jave created an API in Java Spring, and I have a bunch of Fitness Programmes assigned to a User, but this error will occur when I try to get the Object from the JSON in Flutter. I use the http and convert dart packages.
List is not a subtype of type 'Map<String,dynamic>
The problem is this line:
var userModel = Users.fromJson(jsonMap);
This is the getUsers Method:
Future<Users> getUsers() async{
var client = http.Client();
var userModel = null;
var response = await client.get(Uri.parse(Strings.users_url));
try {
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
print(jsonMap);
var userModel = Users.fromJson(jsonMap);
}
}
catch(Exception) {
print(Exception);
return userModel;
}
return userModel;
}
These are the Users and Fitness Programme classes:
// To parse this JSON data, do
//
// final users = usersFromJson(jsonString);
import 'dart:convert';
List<Users> usersFromJson(String str) => List<Users>.from(json.decode(str).map((x) => Users.fromJson(x)));
String usersToJson(List<Users> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Users{
Users({
this.id,
this.email,
this.password,
this.firstName,
this.lastName,
this.birthday,
this.weight,
this.height,
this.fitnessProgrammes,
});
int id;
String email;
String password;
String firstName;
String lastName;
dynamic birthday;
int weight;
int height;
List<FitnessProgramme> fitnessProgrammes;
factory Users.fromJson(Map<String, dynamic> json) => Users(
id: json["id"],
email: json["email"],
password: json["password"],
firstName: json["firstName"],
lastName: json["lastName"],
birthday: json["birthday"],
weight: json["weight"],
height: json["height"],
fitnessProgrammes: List<FitnessProgramme>.from(json["fitnessProgrammes"].map((x) => FitnessProgramme.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"email": email,
"password": password,
"firstName": firstName,
"lastName": lastName,
"birthday": birthday,
"weight": weight,
"height": height,
"fitnessProgrammes": List<dynamic>.from(fitnessProgrammes.map((x) => x.toJson())),
};
}
class FitnessProgramme {
FitnessProgramme({
this.id,
this.name,
this.trainingDifficulty,
});
int id;
String name;
String trainingDifficulty;
factory FitnessProgramme.fromJson(Map<String, dynamic> json) => FitnessProgramme(
id: json["id"],
name: json["name"],
trainingDifficulty: json["trainingDifficulty"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"trainingDifficulty": trainingDifficulty,
};
}
Your API is probably returning an array of users instead of a single user. So the decoded JSON type is List<Map<String, dynamic>>. To resolve this, either loop through each user and instantiate them or make your API return just one specific user.
This code below will probably work and instantiate the first user returned by the API:
var userModel = Users.fromJson(jsonMap[0]);

How to deserialize a string to a object and then set as a generic in flutter

So I have this api call that have a response in the form of: boolean:successful, int:responseCode, String:reponse and T:Data. The Data is a generic, I could be string, int, DataModel etc. My issue is I can not conver the Json or String from of Data to an object as the type is generic. I try to have the deseralization for a data model called event resource. and it works if I do EventResource.fromJson(json['Data']) but I can not set that to Data. I have looked on stack overflow and found this one post similar to mine here. But when I try to implement the answer it fails stating that it can not find the constructor _fromJson even though I had one.
This is how I call fromJson:
ResponseModel responseModel = ResponseModel.fromJson(json.decode(response.body));
My Class (ResponseModel):
import 'EventResource.dart';
import 'dart:convert' show json;
class ResponseModel<T> {
var successful;
int responseCode;
String response;
T Data;
ResponseModel.fromJson(Map<String, dynamic> json){
successful = json['successful'];
responseCode = json['responseCode'];
response = json['response'];
Data = Data is EventResource? EventResource.fromJson(json['Data']) :json['Data']; // this is what I want but cant get to work
}
Map<String, dynamic> toJson() {
return {
'successful': successful,
'responseCode': responseCode,
'response': response,
'Data': Data,
};
}
}
So after sending some time on this I realized rather than have Data be a generic it could be assigned the type var and it would take in any data and we could easily cast it with out having the issues of casting generics etc.
class ResponseModel {
var successful;
int responseCode;
String response;
var Data;
ResponseModel.fromJson(Map<String, dynamic> json){
successful = json['successful'];
responseCode = json['responseCode'];
response = json['response'];
Data = Data is EventResource? EventResource.fromJson(json['Data']) :json['Data'];
}
Map<String, dynamic> toJson() {
return {
'successful': successful,
'responseCode': responseCode,
'response': response,
'Data': Data,
};
}
}

parse json in flutter with map type

i don't understand how parse json to list or any types in flutter
https://jsonplaceholder.typicode.com/photos <= this is json example what i use
and that info is surrounded by [], {}
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
List<Photo> simple =
parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
i expect when json.decode.cast() work, parsed contain each objects but
when i print parsed, it's just one array like [~~~]
why they use cast method with Map<>?
jsonDecode already gives you the list object, so you can optimize the code.
In your case , instead of using
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
List<Photo> simple =
parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
try using
final List<Photo> simple = jsonDecode(responseBody).map((item) => Photo(title: item.title)).toList()
and you avoid having a fromJson function
You do not need to cast the array because they are already a list of objects.
You can use the following to get a list of photo objects:
Future<String> getPhotos() async {
var response = await http.get(
'https://jsonplaceholder.typicode.com/photos');
if (response.statusCode == 200) {
var parsed = json.decode(response.body);
List<Photo> simple = parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
print(simple);
}
}
This is the photo class used.
class Photo {
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
Photo(
{this.albumId, this.id, this.title, this.url, this.thumbnailUrl});
factory Photo.fromJson(Map<dynamic, dynamic> json) {
return Photo(albumId: json['albumId'],
id: json['id'],
title: json['title'],
url: json['url'],
thumbnailUrl: json['thumbnailUrl'],
);
}
}

How to implement T for binding JSON in Flutter model?

I want to use Generic Type Parameter in Flutter, but I'm confused on how to use it with my JSON. Here's the code I've tried:
class BaseMdl {
bool status;
int http_code;
String message;
dynamic data;
BaseMdl({this.status, this.http_code, this.message, List<dynamic> data}) : data = data ?? <dynamic>[];
factory BaseMdl.fromJson(Map<String, dynamic> parsedJson) {
var list = parsedJson['data'] as List;
List<dynamic> dataList = list.map((i) => BaseMdl.fromJson(i)).toList();
return BaseMdl(
status: parsedJson['status'],
http_code: parsedJson['http_code'],
message: parsedJson['message'],
data: dataList
);
}
}
Sorry I'm a beginner in Flutter.