FLUTTER- How to save a List<Object> into shared Preferences? - json

I want to add a product to cart and save it, so that when i open the app again, it is present in the cart. i can add multiple products to cart, so I am looking to save a List<Products>
I want to save a List into sharedPreferences and retrieve the same, but there are no methods for that. I tried using setStringList but I am unable to convert the string into object. And the data is not getting saved also.
my class model-
import 'dart:convert';
class Products {
Products({
required this.title,
required this.price,
required this.description,
required this.image,
this.quantity = 0,
});
final String title;
final double price;
final String description;
final String image;
int quantity;
factory Products.fromRawJson(String str) =>
Products.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Products.fromJson(Map<String, dynamic> json) => Products(
title: json["title"],
price: json["price"].toDouble(),
description: json["description"],
image: json["image"],
);
Map<String, dynamic> toJson() => {
"title": title,
"price": price,
"description": description,
"image": image,
};
}

The shared_preferences library has only the options to save the following.
int
string
List
double
boolean
Reference:
https://pub.dev/documentation/shared_preferences/latest/shared_preferences/SharedPreferences-class.html
But what you could do is to create a List<String> in their jsonEncode form and save it.
Convert the List to List by encoding each of them using https://api.flutter.dev/flutter/dart-convert/jsonEncode.html
Once done you can save it and while decoding it similarly use jsonDecode
Hope this helps.
Thanks!

import 'dart:convert';
//first converts your array to json string store it in session
String strJsonString = json.encode(arrayProducts);
//save strJsonString as String into your session
//when you want to retrive it from session just decode session value
List<Products> = json.decode(strJsonString);

Related

How to loop a list of maps from json api dart/flutter

I have create a class model to receive json data from API
class Competition {
int id;
String name;
String code;
String type;
String emblem;
Competition({
required this.id,
required this.name,
required this.code,
required this.type,
required this.emblem,
});
factory Competition.fromJson(Map<String, dynamic> data) {
return Competition(
id: data["matches"][0]["competition"]['id'],
name: data["matches"][0]["competition"]['name'],
code: data["matches"][0]["competition"]['code'],
type: data["matches"][0]["competition"]['type'],
emblem: data["matches"][0]["competition"]['emblem'],
);
}
}
the code work properly, every time index [0] change the coming data change for the next competition details
i want to make this index change automatically for fetching all data at one time, this index represent list data["matches"].length
My Api service look like
class ServiceApi {
Future<Competition > getmatches() async {
http.Response response = await http.get(
Uri.parse('_url'),
headers: {'X-Auth-Token': '_key'});
String body = response.body;
Map<String, dynamic> data = jsonDecode(body);
Competition compitition = Competition.fromJson(data);
int numberOfCompetition = data["matches"].length;
return matches;
}
}
You can map it like this
List<Competition> compititionList = data['matches'].map((item) => Competition.fromJson(item));
print(compittionList[0].name);
Btw theres a typo(spelling mistake) in competition (just incase you want to fix it)
And thr model should be
class Competition {
int id;
String name;
String code;
String type;
String emblem;
Competition({
required this.id,
required this.name,
required this.code,
required this.type,
required this.emblem,
});
factory Competition.fromJson(Map<String, dynamic> data) {
return Competition(
id: data["competition"]['id'],
name: data["competition"]['name'],
code: data["competition"]['code'],
type: data["competition"]['type'],
emblem: data["competition"]['emblem'],
);
}
}

Using Flutter Freezed to generate code to parse a Json Object

I'm trying to parse some JSON from a file and decided to use Freezed to generate the code. The problem is that (as far as i can tell) there's no way to use a JSON object's name.
So say I have the following JSON object:
{
"uniqueName":{
"website": "https://www.example.com/",
"description": "Some description",
"hosted_demo": false,
"demo": "",
"oss": false,
"source": "",
"other-links": [
{
"title": "Clients",
"site": "https://shlink.io/apps"
}
],
"license": "MIT"
}
}
Then this would be the required dart code for Freezed code (done with instructions from this site):
// 1. import freezed_annotation
import 'package:freezed_annotation/freezed_annotation.dart';
// import any other models we depend on
import 'otherLinks.dart';
// 2. add 'part' files
part 'freezed_files/item.freezed.dart';
part 'generated/item.g.dart';
// 3. add #freezed annotation
#freezed
// 4. define a class with a mixin
class Item with _$Item {
// 5. define a factory constructor
factory Item(
{
// 6. list all the arguments/properties
#Default("") String website,
#Default("") String description,
// ignore: invalid_annotation_target
#Default(false) #JsonKey(name: 'hosted_demo') bool? hostedDemo,
#Default("") String demo,
#Default(false) bool oss,
#Default("") String source,
// ignore: invalid_annotation_target
#Default([]) #JsonKey(name: 'other-links') List<OtherLinks> otherLinks,
#Default("") String license
// 7. assign it with the `_Item` class constructor
}) = _Item;
// 8. define another factory constructor to parse from json
factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json);
}
But i have no idea how to get the uniqueName into the data class. Most other places I've checked assume that the JSON data is formatted with the uniqueName inside JSON object with its own key. While refactoring the JSON file is an option, I would rather not. The whole JSON file is about 12000 lines, making refactoring it a pain.
Do you folks have any idea how I can get uniqueName into the data class?
I'm not sure if this what you're looking for, but how about this?
import 'package:freezed_annotation/freezed_annotation.dart';
import 'otherLinks.dart';
part 'freezed_files/item.freezed.dart';
part 'generated/item.g.dart';
#freezed
class Item with _$Item {
factory Item({
// Add a new property to save the uniqueName
#Default("") String uniqueName,
#Default("") String website,
#Default("") String description,
#Default(false) #JsonKey(name: 'hosted_demo') bool? hostedDemo,
#Default("") String demo,
#Default(false) bool oss,
#Default("") String source,
#Default([]) #JsonKey(name: 'other-links') List<OtherLinks> otherLinks,
#Default("") String license
}) = _Item;
factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json);
// Add this new function
factory Item.fromUniqueJson(Map<String, dynamic> json) {
// Get the uniqueName string key and save it
var uniqueNameKey = json.keys.first;
// Convert the rest of the json object beneath the uniqueName key
return Item.fromJson(json[uniqueNameKey])
// Return the new Item with the uniqueName saved as a property
.copyWith(uniqueName: uniqueNameKey);
}
}
import 'package:freezed_annotation/freezed_annotation.dart';
part 'item.freezed.dart';
part 'item.g.dart';
#freezed
class Item with _$Item {
factory Item({
#Default(UniqueName) UniqueName uniqueName,
}) = _Item;
factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json);
}
#freezed
class UniqueName with _$UniqueName {
factory UniqueName({
#Default('') String website,
#Default('') String description,
#Default(false) bool hostedDemo,
#Default('') String demo,
#Default(false) bool oss,
#Default('') String source,
#Default([]) #JsonKey(name: 'other-links') List<OtherLink> otherLinks,
#Default('') String license,
}) = _UniqueName;
factory UniqueName.fromJson(Map<String, dynamic> json) =>
_$UniqueNameFromJson(json);
}
#freezed
class OtherLink with _$OtherLink {
factory OtherLink({
#Default('') String title,
#Default('') String site,
}) = _OtherLink;
factory OtherLink.fromJson(Map<String, dynamic> json) =>
_$OtherLinkFromJson(json);
}

Getting type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'error in JSON

Im sure you know the problem above. Im wondering how I can solve it. I understand that my data is in form of a list but inside the data class I used map. I don't really understand how I should change it to work, basically I just followed the flutter.dev documentation
So if you are wondering what I did
I basically parsed my data with json_serializable. In testing with test data all worked fine.
My data:
My model contains a title, image & a nested class called modelData.
`import 'package:json_annotation/json_annotation.dart';
import 'modelData.dart';
part 'Modell.g.dart';
#JsonSerializable(explicitToJson: true)
class Modell {
final String title;
final String image;
final ModelData modelData;
Modell(this.title, this.image, this.modelData);
factory Modell.fromJson(Map<String, dynamic> json)
=> _$ModellFromJson(json);
Map<String, dynamic> toJson() => _$ModellToJson(this);}
`
import 'package:json_annotation/json_annotation.dart';
part 'modelData.g.dart';
#JsonSerializable()
class ModelData {
final String title;
ModelData(this.title);
factory ModelData.fromJson(Map<String, dynamic> json)
=> _$ModelDataFromJson(json);
Map<String, dynamic> toJson() => _$ModelDataToJson(this);
}
Im consuming the data with this code:
var modelle = const[];
Future loadDataList() async {
String content = await rootBundle.loadString("assets/ddddddd.json");
List collection = json.decode(content);
List<Modell> _modelle = collection.map((json) => Modell.fromJson(json)).toList();
setState(() {
modelle = _modelle;
});
}
void initState() {
loadDataList();
super.initState();
& if needed here a part of my Data:
[
{
"title":" Alfa Romeo ",
"image":" AlfaRomeo.png ",
"modelData":[
{
"title":" 4C ",
"variantenData":[
]
},
I hope I wrote clear & detailed enough. If Im missing something, sry
-----Update-----
I tested a bit & found out that with simply adding List I no longer get the error, will test further to see whether the solution really works as intended
import 'package:json_annotation/json_annotation.dart';
import 'modelData.dart';
part 'Modell.g.dart';
#JsonSerializable(explicitToJson: true)
class Modell {
final String title;
final String image;
List <ModelData> modelData; //adding List
Modell(this.title, this.image, this.modelData);
factory Modell.fromJson(Map<String, dynamic> json)
=> _$ModellFromJson(json);
Map<String, dynamic> toJson() => _$ModellToJson(this);
}
You have parsed the data and all but the class named Modell should contain a list of ModelData and not a single ModelData. Please change the type to a list of ModelData and it should work hopefully.
class Modell {
final String title;
final String image;
final List<ModelData> modelDataList;
Modell(this.title, this.image, this.modelDataList);
factory Modell.fromJson(Map<String, dynamic> json)
=> _$ModellFromJson(json);
Map<String, dynamic> toJson() => _$ModellToJson(this);}```
In this part:
var modelle = const[];
Future loadDataList() async {
String content = await rootBundle.loadString("assets/ddddddd.json");
List collection = json.decode(content);
List<Modell> _modelle = collection.map((json) => Modell.fromJson(json)).toList();
setState(() {
modelle = _modelle;
});
}
void initState() {
loadDataList();
super.initState();
More specific here:
List collection = json.decode(content);
If you go to Flutter Example will see that collection will return a Map<String, dynamic>.
Try change to:
Map<String, dynamic> collection = json.decode(content);

Trying to fetch json data in flutter

I am trying to fetch json data from this url- "https://jsonplaceholder.typicode.com/photos". And I am following this flutter cookbook tutorial - "https://flutter.dev/docs/cookbook/networking/background-parsing"
My model class looks like this-
class ModelData {
ModelData({
this.albumId,
this.id,
this.title,
this.url,
this.thumbnailUrl,
});
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
factory ModelData.fromJson(Map<String, dynamic> json) => ModelData(
albumId: json["albumId"] as int,
id: json["id"] as int,
title: json["title"] as String,
url: json["url"] as String,
thumbnailUrl: json["thumbnailUrl"] as String,
);
}
And my parseData method looks like this-
List<ModelData> parseData(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed
.map<ModelData>((json) => ModelData().fromJson(json)).toList();
}
The problem is in the last line of this method. It says "error: The method 'fromJson' isn't defined for the type 'ModelData'. (undefined_method at [flutter_rest] lib\main.dart:61)". i don't see any typo problem here. What might going wrong here?
Factory methods act like a static method but you are initialising the class by using ModelData().
Try like this:
ModelData.fromJson(json)

Parse json array without names in Dart

I cannot parse such json
[{"operation_id":"38911","external_id":null,"status":"SUCCESS","date":"2019-12-01T12:30:08.000Z","amount":200}]
The problem lies in array with dynamic names. Here's my POJO:
class PaymentHistoryResponse {
final List<History> list;
PaymentHistoryResponse({this.list});
}
class History {
final String operationId;
final dynamic externalId;
final String status;
final DateTime date;
final int amount;
History({
#required this.operationId,
#required this.externalId,
#required this.status,
#required this.date,
#required this.amount
});
factory History.fromJson(String str) => History.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory History.fromMap(Map<String, dynamic> json) => History(
operationId: json["operation_id"],
externalId: json["external_id"],
status: json["status"],
date: DateTime.parse(json["date"]),
amount: json["amount"]
);
Map<String, dynamic> toMap() => {
"operation_id": operationId,
"external_id": externalId,
"status": status,
"date": date.toIso8601String(),
"amount": amount
};
}
I also receive other json containing arrays, but named ones and I was able to decode them. How can I convert this one? P.s I've also made some research through this site and found some quite similar questions but a bit different and it didn't help me.
Since this is an array and not just a JSON you will need to do something like this:
mList = List<UserModel>.from(response.data.map((i) => UserModel.fromJson(i)));
Hint: for generating models with toJson and fromJson use this website:
https://javiercbk.github.io/json_to_dart/