Get data for class from JSON - Flutter - flutter

I have a class "DilemmData" whose variables are loaded with data like this:
if (prefs.containsKey('dilemms')) {
MyApp.dilemmList = DilemmData.decode(prefs.getString('dilemms')!);
}
Here is the class:
class DilemmData {
double percent;
final String title;
final String date;
final List<DilemmItemData> plus = [];
final List<DilemmItemData> minus = [];
DilemmData({
plus,
minus,
this.percent = 0,
this.title = '',
this.date = '',
});
static Map<String, dynamic> toJson(DilemmData dilemm) => {
'percent': dilemm.percent,
'title': dilemm.title,
'date': dilemm.date,
'plus': dilemm.plus.map((e) => e.toJson()).toList(),
'minus': dilemm.minus.map((e) => e.toJson()).toList(),
};
factory DilemmData.fromJson(Map<String, dynamic> json) {
print('BOBA: ${json['plus']}');
return DilemmData(
plus: json['plus'],
minus: json['minus'],
percent: json['percent'],
title: json['title'],
date: json['date'],
);
}
static String encode(List<DilemmData> dilemm) => json.encode(
dilemm
.map<Map<String, dynamic>>((dil) => DilemmData.toJson(dil))
.toList(),
);
static List<DilemmData> decode(String dilemm) =>
(json.decode(dilemm) as List<dynamic>)
.map<DilemmData>((dil) => DilemmData.fromJson(dil))
.toList();
}
class DilemmItemData {
final int importance;
final String argument;
DilemmItemData({this.importance = 0, this.argument = ''});
Map<String, dynamic> toJson() {
return {
'importance': importance,
'argument': argument,
};
}
factory DilemmItemData.fromJson(Map<String, dynamic> json) {
return DilemmItemData(
importance: json['importance'], argument: json['argument']);
}
static List<DilemmItemData> decode(String item) =>
(json.decode(item) as List<dynamic>)
.map<DilemmItemData>((dil) => DilemmItemData.fromJson(dil))
.toList();
}
But the plus and minus variables are always empty. Does anyone know how to fix this?

The following code snippet would do the trick. Converting a DilemmItemData from JSON was missing.
factory DilemmData.fromJson(Map<String, dynamic> json) {
return DilemmData(
plus: (json['plus'] as List)
.map((json) => DilemmItemData.fromJson(json))
.toList(),
minus: (json['minus'] as List)
.map((json) => DilemmItemData.fromJson(json))
.toList(),
percent: json['percent'],
title: json['title'],
date: json['date'],
);
}

Related

How to get the weather description data and icon along with temp data from openweathermap in flutter?

I managed to get the temp data from the openweathermap. I managed to get the "main" data from this JSON from the internet. But see the weather field, the description is there but can't extract it. There it says "clear", and icon "01d". I will also get icon into flutter, which there is a URL of the images like for example somelink/01d.png and I will get this and load it dynamically:
{"coord":{"lon":28.9833,"lat":41.0351},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":15.87,"feels_like":15.16,"temp_min":15.04,"temp_max":17.09,"pressure":1024,"humidity":63},"visibility":10000,"wind":{"speed":3.09,"deg":120},"clouds":{"all":0},"dt":1668078936,"sys":{"type":1,"id":6970,"country":"TR","sunrise":1668055522,"sunset":1668091839},"timezone":10800,"id":745042,"name":"Istanbul","cod":200}
The thing is, there are several ways I could do this. Futurebuilder inside futurebuilder, I don't know how this works. Or, return an array of data from the fetch function. I am not sure how to do that. I am completely puzzled. Here is my simplified code:
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class TempModel {
final double temp;
final double feels_like;
final double temp_min;
final double temp_max;
final int pressure;
final int humidity;
TempModel({
required this.temp,
required this.feels_like,
required this.temp_min,
required this.temp_max,
required this.pressure,
required this.humidity,
});
factory TempModel.fromJson(Map<String, dynamic> json) {
return TempModel(
temp: json['temp'],
feels_like: json['feels_like'],
temp_min: json['temp_min'],
temp_max: json['temp_max'],
pressure: json['pressure'],
humidity: json['humidity'],
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['temp'] = temp;
data['feels_like'] = feels_like;
data['temp_min'] = temp_min;
data['temp_max'] = temp_max;
data['pressure'] = pressure;
data['humidity'] = humidity;
return data;
}
}
class WeatherModel {
final TempModel main;
WeatherModel({
required this.main,
});
factory WeatherModel.fromJson(Map<String, dynamic> json) {
return WeatherModel(
main: TempModel.fromJson(json['main']),
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['main'] = main;
return data;
}
}
void main() => runApp(const TestPage());
class TestPage extends StatelessWidget {
const TestPage({Key? key}) : super(key: key);
final String sehir1 = 'İstanbul';
final String sehir2 = 'Ankara';
final String sehir3 = 'İzmir';
Future<WeatherModel?> fetchWeather(String sehir) async {
//default olarak.
final http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?q=$sehir&units=metric&appid=666319c58bc57caab32599c61b82c50e'));
print(response.body);
print("");
try {
if (response.statusCode == 200) {
WeatherModel weatherModel =
WeatherModel.fromJson(jsonDecode(response.body));
return weatherModel;
} else {
return null;
}
} catch (e) {
log(e.toString(), name: "error");
return null;
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.orange,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Fetch Data Example'),
),
body: GridView.count(
crossAxisCount: 2,
children: <Widget>[
Expanded(
child: FutureBuilder(
future: fetchWeather(sehir1),
builder: (ctx, AsyncSnapshot<WeatherModel?> snapshot) {
if (!snapshot.hasData || snapshot.hasError) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.network(
'http://openweathermap.org/img/wn/01d.png'),
Text('$sehir1 Hava Durumu'),
Text(
'Hava sıcaklığı ${snapshot.data!.main.temp.toString()}'),
Text(
'Hissedilen sıcaklık ${snapshot.data!.main.feels_like.toString()}'),
],
),
);
}
},
),
),
],
),
),
);
}
}
weather is a list:
{
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
]
}
You have to get the values using its index:
${snapshot.data!.weather[0].icon}
Edit: I see that your model does not accounts entire json. Here's the full one:
// To parse this JSON data, do
//
// final weather = weatherFromJson(jsonString);
import 'dart:convert';
class Weather {
Weather({
required this.coord,
required this.weather,
required this.base,
required this.main,
required this.visibility,
required this.wind,
required this.clouds,
required this.dt,
required this.sys,
required this.timezone,
required this.id,
required this.name,
required this.cod,
});
final Coord coord;
final List<WeatherElement> weather;
final String base;
final Main main;
final int visibility;
final Wind wind;
final Clouds clouds;
final int dt;
final Sys sys;
final int timezone;
final int id;
final String name;
final int cod;
factory Weather.fromRawJson(String str) => Weather.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Weather.fromJson(Map<String, dynamic> json) => Weather(
coord: Coord.fromJson(json["coord"]),
weather: List<WeatherElement>.from(json["weather"].map((x) => WeatherElement.fromJson(x))),
base: json["base"],
main: Main.fromJson(json["main"]),
visibility: json["visibility"],
wind: Wind.fromJson(json["wind"]),
clouds: Clouds.fromJson(json["clouds"]),
dt: json["dt"],
sys: Sys.fromJson(json["sys"]),
timezone: json["timezone"],
id: json["id"],
name: json["name"],
cod: json["cod"],
);
Map<String, dynamic> toJson() => {
"coord": coord.toJson(),
"weather": List<dynamic>.from(weather.map((x) => x.toJson())),
"base": base,
"main": main.toJson(),
"visibility": visibility,
"wind": wind.toJson(),
"clouds": clouds.toJson(),
"dt": dt,
"sys": sys.toJson(),
"timezone": timezone,
"id": id,
"name": name,
"cod": cod,
};
}
class Clouds {
Clouds({
required this.all,
});
final int all;
factory Clouds.fromRawJson(String str) => Clouds.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Clouds.fromJson(Map<String, dynamic> json) => Clouds(
all: json["all"],
);
Map<String, dynamic> toJson() => {
"all": all,
};
}
class Coord {
Coord({
required this.lon,
required this.lat,
});
final double lon;
final double lat;
factory Coord.fromRawJson(String str) => Coord.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Coord.fromJson(Map<String, dynamic> json) => Coord(
lon: json["lon"].toDouble(),
lat: json["lat"].toDouble(),
);
Map<String, dynamic> toJson() => {
"lon": lon,
"lat": lat,
};
}
class Main {
Main({
required this.temp,
required this.feelsLike,
required this.tempMin,
required this.tempMax,
required this.pressure,
required this.humidity,
});
final double temp;
final double feelsLike;
final double tempMin;
final double tempMax;
final int pressure;
final int humidity;
factory Main.fromRawJson(String str) => Main.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Main.fromJson(Map<String, dynamic> json) => Main(
temp: json["temp"].toDouble(),
feelsLike: json["feels_like"].toDouble(),
tempMin: json["temp_min"].toDouble(),
tempMax: json["temp_max"].toDouble(),
pressure: json["pressure"],
humidity: json["humidity"],
);
Map<String, dynamic> toJson() => {
"temp": temp,
"feels_like": feelsLike,
"temp_min": tempMin,
"temp_max": tempMax,
"pressure": pressure,
"humidity": humidity,
};
}
class Sys {
Sys({
required this.type,
required this.id,
required this.country,
required this.sunrise,
required this.sunset,
});
final int type;
final int id;
final String country;
final int sunrise;
final int sunset;
factory Sys.fromRawJson(String str) => Sys.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Sys.fromJson(Map<String, dynamic> json) => Sys(
type: json["type"],
id: json["id"],
country: json["country"],
sunrise: json["sunrise"],
sunset: json["sunset"],
);
Map<String, dynamic> toJson() => {
"type": type,
"id": id,
"country": country,
"sunrise": sunrise,
"sunset": sunset,
};
}
class WeatherElement {
WeatherElement({
required this.id,
required this.main,
required this.description,
required this.icon,
});
final int id;
final String main;
final String description;
final String icon;
factory WeatherElement.fromRawJson(String str) => WeatherElement.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory WeatherElement.fromJson(Map<String, dynamic> json) => WeatherElement(
id: json["id"],
main: json["main"],
description: json["description"],
icon: json["icon"],
);
Map<String, dynamic> toJson() => {
"id": id,
"main": main,
"description": description,
"icon": icon,
};
}
class Wind {
Wind({
required this.speed,
required this.deg,
});
final double speed;
final int deg;
factory Wind.fromRawJson(String str) => Wind.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Wind.fromJson(Map<String, dynamic> json) => Wind(
speed: json["speed"].toDouble(),
deg: json["deg"],
);
Map<String, dynamic> toJson() => {
"speed": speed,
"deg": deg,
};
}

Saving a class within a class - Flutter

I have class "DilemmData" which I need to save:
class DilemmData {
double percent = 0;
final String title;
final String date;
List<DilemmItemData> plus = [];
List<DilemmItemData> minus = [];
DilemmData(
plus,
minus, {
this.percent = 0,
this.title = '',
this.date = '',
});
static Map<String, dynamic> toJson(DilemmData dilemm) {
return {
'percent': dilemm.percent,
'title': dilemm.title,
'date': dilemm.date,
'plus': dilemm.plus.map((e) => e.toJson()).toList(),
'minus': dilemm.minus.map((e) => e.toJson()).toList(),
};
}
factory DilemmData.fromJson(Map<String, dynamic> json) {
return DilemmData(
json['plus'],
json['minus'],
percent: json['percent'],
title: json['title'],
date: json['date'],
);
}
static String encode(List<DilemmData> pressure) => json.encode(
pressure
.map<Map<String, dynamic>>((dil) => DilemmData.toJson(dil))
.toList(),
);
static List<DilemmData> decode(String dilemm) =>
((json.decode(dilemm) ?? []) as List<dynamic>)
.map<DilemmData>((dil) => DilemmData.fromJson(dil))
.toList();
}
class DilemmItemData {
final int importance;
final String argument;
DilemmItemData({this.importance = 0, this.argument = ''});
Map<String, dynamic> toJson() {
return {
'importance': importance,
'argument': argument,
};
}
factory DilemmItemData.fromJson(Map<String, dynamic> json) {
return DilemmItemData(
importance: json['importance'], argument: json['argument']);
}
}
There is save function:
DilemmData dilemm = DilemmData(
percent: 0,
title: controller.text,
date: clockString);
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
String data = jsonEncode(dilemm);
sharedPreferences.setString('dilemms', data);
But when i try to save i get this error: JsonUnsupportedObjectError (Converting object to an encodable object failed: Instance of 'DilemmData'). Does anyone know how to save?
StackOverflow says I have a lot of code, but I don't know what else to write, I'll write random letters for this: shdjfhjjsdfjhwehfwouiehuwefuwefuwheugweghuweghuiweghuwueghuweweugihwueighuwhguwhgu
Here is the function to get the data:
Future loadDillems() async {
SharedPreferences sharedPreferences = await
SharedPreferences.getInstance();
if (sharedPreferences.containsKey('dilemms')) {
Map<String, dynamic> data =
jsonDecode(sharedPreferences.getString('dilemms')!);
MyApp.dilemmList = DilemmData.fromJson(data) as List<DilemmData>;
}
}
When converting the "top" class using its toJson() method, make sure that the subsequent classes' toJson() methods is also called. As such:
'plus': dilemm.plus.map((e) => e.toJson()).toList(),
And you of course have to implement toJson() and fromJson() in DilemmItemData as well.
Edit:
Okey, so a couple of alternatives. First of all, you had to create the new toJson() (and soon also fromJson()) methods. That is good.
As #Ivo wrote, if you pass the object to jsonEncode as you do now, then the methods cannot be static. But you could also pass DilemmData.toJson(dilemm) as:
String data = jsonEncode(DilemmData.toJson(dilemm));
But I'd recommend as #Ivo wrote to make it non-static, as you did with the new toJson method, and of course keep the toJson in DilemmItemData, and I suggest that you write the fromJson as well...
Second edit:
Your fromJson have to be a bit sharper. Something like this:
DilemmData(
(json['plus'] as List<dynamic>)
.map((e) => DilemmItemData.fromJson(e as Map<String, dynamic>))
.toList(),
Edit 3:
You are saving one DilemmData, so you have to read it as one (1) DilemmData. Remove the as List<DilemmData>; It is not all of a sudden a List when it is one object that you save (String data = jsonEncode(dilemm);)
So do as follows:
final oneDilemmData = DilemmData.fromJson(data);
I think you need to make your toJson() non static like this:
Map<String, dynamic> toJson() {
return {
'percent': percent,
'title': title,
'date': date,
'plus': plus,
'minus': minus,
};
}
your encode could be like this then:
static String encode(List<DilemmData> pressure) => json.encode(
pressure
.map<Map<String, dynamic>>((dil) => dil.toJson())
.toList(),
);

Flutter: Dart Error: RangeError (index): Invalid value: Only valid value is 0: 1

Hey guys I am new to Flutter and trying to build a variation selector for an eCommerce application. I am getting this error while trying to build a size variation widget for the size-color variation. It works for size only or color only variation. This is the error RangeError (index): Invalid value: Only valid value is 0: 1.
Also, when I print the length of the array, I am getting the value 1.
The idea is to show the available sizes when someone clicks on a color that gets displayed without any issues. but while trying to show the size, facing this error.
This is the code
///size widget
class SelectSizeWidget extends StatefulWidget {
SelectSizeWidget({
Key? key,
}) : super(key: key);
#override
_SelectSizeWidgetState createState() => _SelectSizeWidgetState();
}
class _SelectSizeWidgetState extends State<SelectSizeWidget> {
#override
Widget build(BuildContext context) {
return Consumer<ProductController>(
builder: (_,model,__) {
return Wrap(
spacing: 8,
runSpacing: 8,
children: List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {
if(model.sizeColour.isNotEmpty) {
if(model.selectedColour != null || model.selectedColour != ""){
var _res = model.sizeColour
.where((element) =>
element.var2!.toUpperCase() == model.selectedColour)
.toList();
var _size = _res[index];
return buildSize(_size);
} else {
var _res = model.sizeColour.toList();
var _size = _res[index];
return buildSize(_size);
}
} else if (model.size.isNotEmpty) {
var _size = model.size[index];
return buildSize(_size);
}else if(model.materialSize.isNotEmpty){
var _res = model.materialSize.where((element) =>
element.var1.toUpperCase() == model.selectedMaterial)
.toList();
var _size = _res[index];
return buildSize(_size);
}else{
return SizedBox.shrink();
}
}),
);
}
);
}
SizedBox buildSize(Variant size) {
return SizedBox(
height: 38,
child: RawChip(
label: Text(size.var1),
labelStyle: TextStyle(color: Theme.of(context).hintColor),
padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7),
backgroundColor: Theme.of(context).focusColor.withOpacity(0.05),
selectedColor: Theme.of(context).focusColor.withOpacity(0.2),
selected: size.varId == context.read<ProductController>().selectedVariation,
shape: StadiumBorder(side: BorderSide(color: Theme.of(context).focusColor.withOpacity(0.05))),
onSelected: (bool value) {
context.read<ProductController>().setSize(size.varId);
},
),
);
}
}
Productcontroller - for detail
List<Variant> size = [];
List<Variant> colour = [];
List<Variant> sizeColour = [];
List<String> ss = [];
List<String> cc = [];
Future<bool> getProductDetails({required String slug}) async {
final val = await ApiProvider().getProductDetails(slug: slug);
if (val.statusCode == 200 || val.statusCode == 201) {
product = productDetailsResponseFromJson(jsonEncode(val.data));
/// variation
if (product!.variants) {
clearAll();
List<Map<int, Set<String>>> sc = [];
List<String> s = [];
List<String> c = [];
selectedVariation = product!.prdtVari.first.id;
for (var each in product!.prdtVari) {
var _var = each.variation.toLowerCase();
if (_var == 'colour') {
colour.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap));
c.add(each.variationTypes.first.name);
notifyListeners();
} else if (_var == 'size') {
size.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap));
s.add(each.variationTypes.first.name);
notifyListeners();
} else if (_var == 'size-colour') {
sc.add({
each.id: {
each.variationTypes.first.name,
each.variationTypes.last.name
}
});
sizeColour.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap,
var2: each.variationTypes.last.name,
typeMap2: each.variationTypes.last.typeMap));
s.add(each.variationTypes.first.name);
c.add(each.variationTypes.last.name);
notifyListeners();
}
}
ss = s.toSet().toList();
cc = c.toSet().toList();
if(cc.isNotEmpty){
if(product!.prdtVari.first.variation.toLowerCase() == "colour"){
selectedColour = colour.where((element) => element.varId == selectedVariation!).first.var1.toUpperCase();
} else if(product!.prdtVari.first.variation.toLowerCase() == "size-colour") {
selectedColour = sizeColour.where((element) => element.varId == selectedVariation!).first.var2!.toUpperCase();
}
};
notifyListeners();
}
isLoading = false;
notifyListeners();
return true;
} else {
isLoading = false;
notifyListeners();
return false;
}
}
API model
// To parse this JSON data, do
//
// final productDetailsResponse = productDetailsResponseFromJson(jsonString);
import 'dart:convert';
ProductDetailsResponse productDetailsResponseFromJson(String str) => ProductDetailsResponse.fromJson(json.decode(str));
String productDetailsResponseToJson(ProductDetailsResponse data) => json.encode(data.toJson());
class ProductDetailsResponse {
ProductDetailsResponse({
required this.category,
required this.title,
required this.variants,
required this.slug,
required this.averageReview,
required this.countReview,
required this.productDetailsInfo,
required this.prdtImg,
required this.prdtVari,
});
int category;
String title;
bool variants;
String slug;
double averageReview;
int countReview;
ProductDetailsInfo productDetailsInfo;
List<ProductDetailsImages> prdtImg;
List<ProductDetailsVariation> prdtVari;
factory ProductDetailsResponse.fromJson(Map<String, dynamic> json) => ProductDetailsResponse(
category: json["category"],
title: json["title"],
variants: json["var"],
slug: json["slug"],
averageReview: json["rating"],
countReview: json["rCount"],
productDetailsInfo: ProductDetailsInfo.fromJson(json["prdtInfo"]),
prdtImg: List<ProductDetailsImages>.from(json["prdtImg"].map((x) => ProductDetailsImages.fromJson(x))),
prdtVari: List<ProductDetailsVariation>.from(json["prdtVari"].map((x) => ProductDetailsVariation.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category": category,
"title": title,
"var": variants,
"slug": slug,
"rating": averageReview,
"rCount": countReview,
"prdtInfo": productDetailsInfo.toJson(),
"prdtImg": List<dynamic>.from(prdtImg.map((x) => x.toJson())),
"prdtVari": List<dynamic>.from(prdtVari.map((x) => x.toJson())),
};
}
class ProductDetailsImages {
ProductDetailsImages({
required this.id,
required this.images,
required this.cover,
});
int id;
String? images;
bool cover;
factory ProductDetailsImages.fromJson(Map<String, dynamic> json) => ProductDetailsImages(
id: json["id"],
images: json["images"],
cover: json["cover"],
);
Map<String, dynamic> toJson() => {
"id": id,
"images": images,
"cover": cover,
};
}
class ProductDetailsInfo {
ProductDetailsInfo({
required this.brand,
required this.mrp,
required this.price,
required this.inStock,
required this.desc,
required this.shipCost,
required this.condition,
});
String? brand;
double mrp;
double price;
String inStock;
String desc;
double? shipCost;
String condition;
factory ProductDetailsInfo.fromJson(Map<String, dynamic> json) => ProductDetailsInfo(
brand: json["brd"],
mrp: json["mrp"],
price: json["price"],
inStock: json["iStock"],
desc: json["desc"],
shipCost: json["shCost"],
condition: json["con"],
);
Map<String, dynamic> toJson() => {
"brand": brand,
"mrp": mrp,
"price": price,
"iStock": inStock,
"desc": desc,
"shCost": shipCost,
"con": condition,
};
}
class ProductDetailsVariation {
ProductDetailsVariation({
required this.id,
required this.variation,
required this.mrp,
required this.price,
required this.inStock,
required this.images,
required this.variationTypes,
});
int id;
String variation;
double mrp;
double price;
String inStock;
List<ProductDetailsImages> images;
List<ProductDetailsVariationType> variationTypes;
factory ProductDetailsVariation.fromJson(Map<String, dynamic> json) => ProductDetailsVariation(
id: json["id"],
variation: json["vAtion"],
mrp: json["mrp"],
price: json["price"],
inStock: json["iStock"],
images: List<ProductDetailsImages>.from(json["imgs"].map((x) => ProductDetailsImages.fromJson(x))),
variationTypes: List<ProductDetailsVariationType>.from(json["vTypes"].map((x) => ProductDetailsVariationType.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"vAtion": variation,
"mrp": mrp,
"price": price,
"iStock": inStock,
"imgs": List<dynamic>.from(images.map((x) => x.toJson())),
"vTypes": List<dynamic>.from(variationTypes.map((x) => x.toJson())),
};
}
class ProductDetailsVariationType {
ProductDetailsVariationType({
required this.id,
required this.name,
required this.typeMap,
});
int id;
String name;
String typeMap;
factory ProductDetailsVariationType.fromJson(Map<String, dynamic> json) => ProductDetailsVariationType(
id: json["id"],
name: json["name"],
typeMap: json["tMap"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"tMap": typeMap,
};
}
Thanks
List.generate is using model.ss.length or model.size.length to generate your list like you instructed on this line
List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {
It means index <= model.ss.length-1 or index <= model.size.length-1. Then you did
var _res = model.sizeColour.where((element) => element.var2!.toUpperCase() == model.selectedColour).toList();
So if var _size = _res[index] throw RangeError it means _res.length < model.ss.length-1 or _res.length < model.size.length-1 but it should be equal, so the solution is to make sure the 3 arrays have the same length.
Try replacing the 'or' with 'and'
if(model.selectedColour != null && model.selectedColour != "")
Since you used or it is always true if either of the condition is met. So even it's empty that variable was assigned with empty value.
Error often happen when you render data in list but you hasn't data you try check null in code because you not have controller call api or data any where
you can check line code has "if" ...
check length of list > 0
"var _size = _res[index];" maybe index null
I could not read all the code and test it, but I got that error before. When?
for example,
List<String> myList = [1 , 2 ,3 ,4];
child : ListView(
children: [
Text("${mylist[0]}"),
Text("${mylist[1]}"),
Text("${mylist[2]}"),
Text("${mylist[3]}"),
Text("${mylist[4]}"),
]
) ;
so you have four items in the list which mean your index will be just until 3 if you add more than the items in the list it will show that error.
I hope I was able to explain.

how to use for loop in flutter

i want to use for loop i need "photoThumbnailImagePath" array but i am not able to work on it...! i am trying to get array index of image path but i getting only one image.....! my value is not printing ! i gave u my code and my json data...! plz show me how it works how should i print my image value
if (response.statusCode == 200) {
var jsonResponse = json.decode(response.body);
print("laavvvvvvvvv :" + jsonResponse.toString());
var azim = List<FolderList>.from(jsonResponse["FolderList"].map((x) => FolderList.fromJson(x)));
// ignore: unnecessary_statements
print("printing");
for (final cam in azim){
print("photoThumbnailImagePath:" + cam.photoList[0].photoThumbnailImagePath.toString()); //i am getting here first image only i want all alisting array how
Photlistinng = [cam.photoList[0].photoThumbnailImagePath];
print("Photlistinng : " + Photlistinng.toString());
};
return AllPhotoListing.fromJson(json.decode(response.body));
} else {
// If the server did not return a 201 CREATED response,
// then throw an exception.
throw Exception('Failed to load data');
}
this my my code when api succesful then i use for loop but something wrong with my code so plz check
here is my json data converter
import 'dart:convert';
AllPhotoListing allPhotoListingFromJson(String str) => AllPhotoListing.fromJson(json.decode(str));
String allPhotoListingToJson(AllPhotoListing data) => json.encode(data.toJson());
class AllPhotoListing {
AllPhotoListing({
this.successCode,
this.successMessage,
this.totalPhotos,
this.totalLikes,
this.totalComments,
this.totalShared,
this.totalSelectedPhotosForAlbum,
this.watermarkType,
this.watermarkLogo,
this.watermarkText,
this.watermarkFont,
this.watermarkFontColor,
this.watermarkScaleHeight,
this.watermarkScaleWidth,
this.watermarkOpacity,
this.watermarkFontSize,
this.watermarkPlacement,
this.folderList,
});
String successCode;
String successMessage;
int totalPhotos;
int totalLikes;
int totalComments;
int totalShared;
int totalSelectedPhotosForAlbum;
String watermarkType;
String watermarkLogo;
String watermarkText;
String watermarkFont;
String watermarkFontColor;
int watermarkScaleHeight;
int watermarkScaleWidth;
double watermarkOpacity;
int watermarkFontSize;
String watermarkPlacement;
List<FolderList> folderList;
factory AllPhotoListing.fromJson(Map<String, dynamic> json) => AllPhotoListing(
successCode: json["SuccessCode"],
successMessage: json["SuccessMessage"],
totalPhotos: json["TotalPhotos"],
totalLikes: json["TotalLikes"],
totalComments: json["TotalComments"],
totalShared: json["TotalShared"],
totalSelectedPhotosForAlbum: json["TotalSelectedPhotosForAlbum"],
watermarkType: json["WatermarkType"],
watermarkLogo: json["WatermarkLogo"],
watermarkText: json["WatermarkText"],
watermarkFont: json["WatermarkFont"],
watermarkFontColor: json["WatermarkFontColor"],
watermarkScaleHeight: json["WatermarkScaleHeight"],
watermarkScaleWidth: json["WatermarkScaleWidth"],
watermarkOpacity: json["WatermarkOpacity"].toDouble(),
watermarkFontSize: json["WatermarkFontSize"],
watermarkPlacement: json["WatermarkPlacement"],
folderList: List<FolderList>.from(json["FolderList"].map((x) => FolderList.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"SuccessCode": successCode,
"SuccessMessage": successMessage,
"TotalPhotos": totalPhotos,
"TotalLikes": totalLikes,
"TotalComments": totalComments,
"TotalShared": totalShared,
"TotalSelectedPhotosForAlbum": totalSelectedPhotosForAlbum,
"WatermarkType": watermarkType,
"WatermarkLogo": watermarkLogo,
"WatermarkText": watermarkText,
"WatermarkFont": watermarkFont,
"WatermarkFontColor": watermarkFontColor,
"WatermarkScaleHeight": watermarkScaleHeight,
"WatermarkScaleWidth": watermarkScaleWidth,
"WatermarkOpacity": watermarkOpacity,
"WatermarkFontSize": watermarkFontSize,
"WatermarkPlacement": watermarkPlacement,
"FolderList": List<dynamic>.from(folderList.map((x) => x.toJson())),
};
}
class FolderList {
FolderList({
this.folderId,
this.title,
this.totalCount,
this.photoList,
});
int folderId;
String title;
int totalCount;
List<PhotoList> photoList;
factory FolderList.fromJson(Map<String, dynamic> json) => FolderList(
folderId: json["FolderId"],
title: json["Title"],
totalCount: json["TotalCount"],
photoList: List<PhotoList>.from(json["PhotoList"].map((x) => PhotoList.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"FolderId": folderId,
"Title": title,
"TotalCount": totalCount,
"PhotoList": List<dynamic>.from(photoList.map((x) => x.toJson())),
};
}
class PhotoList {
PhotoList({
this.photoId,
this.photoMainImagePath,
this.photoThumbnailImagePath, // i need this array in my api call
this.photoPreviewImagePath,
this.isSelectedPhoto,
this.isLikedPhoto,
this.photoSelectedCustomers,
this.photoSelectedPhotographerProfile,
});
int photoId;
String photoMainImagePath;
String photoThumbnailImagePath;
String photoPreviewImagePath;
int isSelectedPhoto;
int isLikedPhoto;
List<PhotoSelectedCustomer> photoSelectedCustomers;
String photoSelectedPhotographerProfile;
factory PhotoList.fromJson(Map<String, dynamic> json) => PhotoList(
photoId: json["PhotoId"],
photoMainImagePath: json["PhotoMainImagePath"],
photoThumbnailImagePath: json["PhotoThumbnailImagePath"],
photoPreviewImagePath: json["PhotoPreviewImagePath"],
isSelectedPhoto: json["IsSelectedPhoto"],
isLikedPhoto: json["IsLikedPhoto"],
photoSelectedCustomers: List<PhotoSelectedCustomer>.from(json["PhotoSelectedCustomers"].map((x) =>
PhotoSelectedCustomer.fromJson(x))),
photoSelectedPhotographerProfile: json["PhotoSelectedPhotographerProfile"],
);
Map<String, dynamic> toJson() => {
"PhotoId": photoId,
"PhotoMainImagePath": photoMainImagePath,
"PhotoThumbnailImagePath": photoThumbnailImagePath,
"PhotoPreviewImagePath": photoPreviewImagePath,
"IsSelectedPhoto": isSelectedPhoto,
"IsLikedPhoto": isLikedPhoto,
"PhotoSelectedCustomers": List<dynamic>.from(photoSelectedCustomers.map((x) => x.toJson())),
"PhotoSelectedPhotographerProfile": photoSelectedPhotographerProfile,
};
}
class PhotoSelectedCustomer {
PhotoSelectedCustomer({
this.profilePicture,
});
String profilePicture;
factory PhotoSelectedCustomer.fromJson(Map<String, dynamic> json) => PhotoSelectedCustomer(
profilePicture: json["ProfilePicture"],
);
Map<String, dynamic> toJson() => {
"ProfilePicture": profilePicture,
};
}
you can try this :
for(int i=0; i<azim.length; i++){
//print here
}

Unhandled Exception: Converting object to an encodable object failed: Instance of 'DateTime'

I have a Model of Task =>
class Task {
Task({this.isDone,this.name,this.time,this.priorityValue});
final String name;
bool isDone;
final DateTime time;
int priorityValue;
factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
name: jsonData['name'],
isDone: false,
time: jsonData['time'],
priorityValue: jsonData['priorityValue'],
);
}
toJSONEncodable() {
Map<String, dynamic> m = new Map();
m['name'] = name;
m['isDone'] = isDone;
m['time'] = time;
m['priorityValue'] = priorityValue;
return m;
}
static Map<String, dynamic> toMap(Task task) => {
'name': task.name,
'isDone': task.isDone,
'time': task.time,
'priorityValue': task.priorityValue,
};
}
and When using the localStorage package to save some list of objects I got this error =>
(Flutter) Unhandled Exception: Converting object to an encodable object failed: Instance of 'DateTime'
_saveToStorage() {
storage.setItem('tasks', list.toJSONEncodable());
print("Saved");
}
i tried to use .toString() but then i get this error => type 'String' is not a subtype of type 'int' of 'index'
any Idea to save Datetime on LocalStorage package?
Update:
factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
name: jsonData['name'],
isDone: false,
time: jsonData["time"] == null ? null : DateTime.parse(jsonData["time"]),
priorityValue: jsonData['priorityValue'],
);
}
toJSONEncodable() {
Map<String, dynamic> m = new Map();
m['name'] = name;
m['isDone'] = isDone;
m['time'] = time == null ? null : time.toIso8601String();
m['priorityValue'] = priorityValue;
return m;
}
static Map<String, dynamic> toMap(Task task) => {
'name': task.name,
'isDone': task.isDone,
'time': task.time,
'priorityValue': task.priorityValue,
};
var items = storage.getItem('tasks');
if (items != null) {
list.items = List<Task>.from(
(items as List).map(
(item) => Task(
name: item['name'],
isDone: item['isDone'],
time: DateTime.parse(item['time']),
priorityValue: items['priorityValue'],
),
),
);
}
after the update i got this error "type 'String' is not a subtype of type 'int' of 'index'"
Update2:
var items = storage.getItem('tasks');
if (items != null) {
final decodedJson = jsonDecode(items);
list.items = (decodedJson as List)
.map((e) => Task.fromJson(e))
.toList();
final task = list.items.first;
print("${task.name}");
// list.items = List<Task>.from(
// (items as List).map(
// (item) => Task(
// name: item['name'],
// isDone: item['isDone'],
// time: DateTime.parse(item['time']),
// priorityValue: items['priorityValue'],
// ),
// ),
// );
}
fter the second update i got "type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'"
Fixed
i changed the DaeTme toa String in the model and convert the time to a string when got it by
"${selectedDate.toLocal()}".split(' ')[0]
use toJson
"changeDate": changeDate == null ? null : changeDate.toIso8601String(),
and fromJson
changeDate: json["changeDate"] == null ? null : DateTime.parse(json["changeDate"]),
I'd highly recommend you to use Retrofit and json_serializable for describing your API
It could look like so:
import 'package:json_annotation/json_annotation.dart';
part 'task.g.dart';
#JsonSerializable(nullable: false, explicitToJson: true)
class Task {
final String name;
bool isDone;
final DateTime time;
int priorityValue;
Task({this.isDone, this.name, this.time, this.priorityValue});
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
Map<String, dynamic> toJson() => _$TaskToJson(this);
}
after that you need to run build_runner:
flutter pub run build_runner build
and it will generate you both toJson and fromJson methods without any pain:
Task _$TaskFromJson(Map<String, dynamic> json) {
return Task(
isDone: json['isDone'] as bool,
name: json['name'] as String,
time: DateTime.parse(json['time'] as String),
priorityValue: json['priorityValue'] as int,
);
}
Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
'name': instance.name,
'isDone': instance.isDone,
'time': instance.time.toIso8601String(),
'priorityValue': instance.priorityValue,
};
You can check out the test:
void main() {
test('Task should be parsed from json', () {
const json = '''
[
{
"name": "testing",
"isDone": false,
"time": "2021-01-12T13:57:10.705476",
"priorityValue": 0
}
]
''';
final List decodedJson = jsonDecode(json);
final List<Task> list = decodedJson.map((e) => Task.fromJson(e)).toList();
final Task task = list.first;
expect(task.name, 'testing');
expect(task.isDone, false);
expect(task.time, DateTime.parse("2021-01-12T13:57:10.705476"));
expect(task.priorityValue, 0);
});
}