So... I got this One Call Api which also includes forecast for 7 days. I managed to get display the current weather (temp, and icon) but how do I get the forecast for the next 4 days?
My API: https://api.openweathermap.org/data/2.5/onecall?lat=lat&lon=lon&exclude=minutely,hourly,alerts&cnt=4&appid={MyKey}&units=metric
My model:
class CurrentWeatherModel {
final WeatherInfo weatherInfo;
final double temp;
const CurrentWeatherModel({
required this.weatherInfo, required this.temp
});
factory CurrentWeatherModel.fromJson(json){
return CurrentWeatherModel(
weatherInfo: WeatherInfo.fromJson(json['weather'][0]),
temp: json['temp'],
);
}
}
class HourlyWeatherModel {
final double temp;
final WeatherInfo weatherInfo;
const HourlyWeatherModel(
{
required this.temp,
required this.weatherInfo
}
);
factory HourlyWeatherModel.fromJson(json){
return HourlyWeatherModel(
temp: json['temp'],
weatherInfo: WeatherInfo.fromJson(json['weather'][0])
);
}
}
class DailyWeatherInfoModel {
final TempModel dailyTemp;
final WeatherInfo weatherInfo;
final DateTime date;
final int dt;
const DailyWeatherInfoModel(
{
required this.dailyTemp,
required this.weatherInfo,
required this.date,
required this.dt,
}
);
factory DailyWeatherInfoModel.fromJson(json){
return DailyWeatherInfoModel(
dailyTemp: TempModel.fromJson(json['temp']),
dt: json['dt'],
date: DateTime.fromMillisecondsSinceEpoch(json['dt'] * 1000,
isUtc: true),
weatherInfo: WeatherInfo.fromJson(json['weather'][0]),
);
}
}
class TempModel {
final double day;
final double min;
final double max;
const TempModel(
{
required this.day,
required this.min,
required this.max
}
);
factory TempModel.fromJson(json){
return TempModel(
day: json['day'],
min: json['min'],
max: json['max']
);
}
}
class WeatherInfo {
final String? description;
final String? icon;
WeatherInfo({this.description, this.icon});
factory WeatherInfo.fromJson(Map<String, dynamic> json) {
final description = json['description'];
final icon = json['icon'];
return WeatherInfo(description: description, icon: icon);
}
}
class WeatherForecastResponse {
final CurrentWeatherModel current;
final HourlyWeatherModel hourly;
final DailyWeatherInfoModel daily;
String get iconCurrentWeatherUrl{
return 'https://merakiapp.be/wp-content/uploads/2022/04/${current.weatherInfo.icon}.png';
}
String get iconDailyWeatherUrl{
return 'https://merakiapp.be/wp-content/uploads/2022/04/${daily.weatherInfo.icon}.png';
}
const WeatherForecastResponse(
{
required this.current,
required this.daily,
required this.hourly
}
);
factory WeatherForecastResponse.fromJson(json){
return WeatherForecastResponse(
current: CurrentWeatherModel.fromJson(json['current']),
hourly: HourlyWeatherModel.fromJson(json['hourly'][0]),
daily: DailyWeatherInfoModel.fromJson(json['daily'][0])
);
}
}
My Response:
Future<WeatherForecastResponse> getForecast(double lat, double lon) async {
try {
String api = 'https://api.openweathermap.org/data/2.5/onecall';
String appId = 'MyAPIKey';
String units = 'metric';
String cnt = '4';
String url = '$api?lat=$lat&lon=$lon&cnt=$cnt&appid=$appId&units=$units';
final response = await http.get(Uri.parse(url));
final json = jsonDecode(response.body);
return WeatherForecastResponse.fromJson(json);
} catch (e) {
rethrow;
}
}
Respons object:
void _currentWeather() async {
await FirebaseFirestore.instance.collection('Users').doc(currentUser).get().then((value) => _userLocation = value.data()!['Location']);
setState(() {
lat = _userLocation.latitude;
lon = _userLocation.longitude;
});
final response = await _dataWeatherService.getForecast(lat!, lon!);
setState(() {
temp = response.current.temp.round();
weather = response.current.weatherInfo.description;
icon = response.iconCurrentWeatherUrl;
});
}
void _dailyForecast() async {
final response = await _dataWeatherService.getForecast(lat!, lon!);
setState(() {
tempDaily = response.daily.dailyTemp.day.round();
weatherDaily = response.daily.weatherInfo.description;
iconDaily = response.iconDailyWeatherUrl;
date = response.daily.date;
});
}
JSON from OneCall API:
{
"lat": 33.44,
"lon": -94.04,
"timezone": "America/Chicago",
"timezone_offset": -21600,
"current": {
"dt": 1618317040,
"sunrise": 1618282134,
"sunset": 1618333901,
"temp": 284.07,
"feels_like": 282.84,
"pressure": 1019,
"humidity": 62,
"dew_point": 277.08,
"uvi": 0.89,
"clouds": 0,
"visibility": 10000,
"wind_speed": 6,
"wind_deg": 300,
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"rain": {
"1h": 0.21
}
},
"minutely": [
{
"dt": 1618317060,
"precipitation": 0.205
},
...
},
"hourly": [
{
"dt": 1618315200,
"temp": 282.58,
"feels_like": 280.4,
"pressure": 1019,
"humidity": 68,
"dew_point": 276.98,
"uvi": 1.4,
"clouds": 19,
"visibility": 306,
"wind_speed": 4.12,
"wind_deg": 296,
"wind_gust": 7.33,
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"pop": 0
},
...
}
"daily": [
{
"dt": 1618308000,
"sunrise": 1618282134,
"sunset": 1618333901,
"moonrise": 1618284960,
"moonset": 1618339740,
"moon_phase": 0.04,
"temp": {
"day": 279.79,
"min": 275.09,
"max": 284.07,
"night": 275.09,
"eve": 279.21,
"morn": 278.49
},
"feels_like": {
"day": 277.59,
"night": 276.27,
"eve": 276.49,
"morn": 276.27
},
"pressure": 1020,
"humidity": 81,
"dew_point": 276.77,
"wind_speed": 3.06,
"wind_deg": 294,
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": 56,
"pop": 0.2,
"rain": 0.62,
"uvi": 1.93
},
...
},
"alerts": [
{
"sender_name": "NWS Tulsa",
"event": "Heat Advisory",
"start": 1597341600,
"end": 1597366800,
"description": "...HEAT ADVISORY REMAINS IN EFFECT FROM 1 PM THIS AFTERNOON TO\n8 PM CDT THIS EVENING...\n* WHAT...Heat index values of 105 to 109 degrees expected.\n* WHERE...Creek, Okfuskee, Okmulgee, McIntosh, Pittsburg,\nLatimer, Pushmataha, and Choctaw Counties.\n* WHEN...From 1 PM to 8 PM CDT Thursday.\n* IMPACTS...The combination of hot temperatures and high\nhumidity will combine to create a dangerous situation in which\nheat illnesses are possible.",
"tags": [
"Extreme temperature value"
]
},
...
]
I would change your WeatherForecastResponse to have a list of DailyWeatherInfoModel vs a single model.
class WeatherForecastResponse {
final CurrentWeatherModel current;
final HourlyWeatherModel hourly;
final List<DailyWeatherInfoModel> daily;
...
}
Then you parse a full list in the fromJson constructor
factory WeatherForecastResponse.fromJson(json) {
final dailyResponse = json['daily'] as List;
final dailyForecastList = <DailyWeatherInfoModel>[];
for (final day in dailyResponse) {
dailyForecastList.add(DailyWeatherInfoModel.fromJson(day));
}
return WeatherForecastResponse(
current: CurrentWeatherModel.fromJson(json['current']),
hourly: HourlyWeatherModel.fromJson(json['hourly'][0]),
daily: dailyForecastList);
}
I would also just put the icon url in each daily/hourly model. This way you have a fully self contained list of DailyWeatherInfoModel with everything you need.
class DailyWeatherInfoModel {
final TempModel dailyTemp;
final WeatherInfo weatherInfo;
final DateTime date;
final int dt;
final String iconUrl; // adding this
const DailyWeatherInfoModel({
required this.dailyTemp,
required this.weatherInfo,
required this.date,
required this.dt,
required this.iconUrl,
});
factory DailyWeatherInfoModel.fromJson(json) {
final weatherInfo = WeatherInfo.fromJson(json['weather'][0]);
final iconUrl =
'https://merakiapp.be/wp-content/uploads/2022/04/${weatherInfo.icon}.png'; // init iconUrl here
return DailyWeatherInfoModel(
dailyTemp: TempModel.fromJson(json['temp']),
dt: json['dt'],
date: DateTime.fromMillisecondsSinceEpoch(json['dt'] * 1000, isUtc: true),
weatherInfo: weatherInfo,
iconUrl: iconUrl,
);
}
}
You can apply the same concept to the hourly forecast as well.
Related
I have 2 things I want to compare and return a list of Strings for each of the matching Ids with the corresponding names. Example: I have a list of "genre_ids": [16, 878, 28] from a movie, and from another API I get a list of objects with id and name of the genres, { "id": 878, "name": "Science Fiction" }. Now I want to compare the list of genre_ids with the list of objects with ids and names and return a List of names with all the matching Ids. How do I do that? I tried using the .where() option but failed miserably.
JSON from genre list:
{
"genres": [
{
"id": 28,
"name": "Action"
},
{
"id": 12,
"name": "Adventure"
},
{
"id": 16,
"name": "Animation"
},
{
"id": 35,
"name": "Comedy"
},
{
"id": 10749,
"name": "Romance"
},
{
"id": 878,
"name": "Science Fiction"
},
]
}
JSON from movie list:
"results": [
{
"adult": false,
"genre_ids": [
16,
878,
28
],
"id": 610150,
"release_date": "2022-06-11",
"title": "Dragon Ball Super: Super Hero",
"vote_average": 7.5,
"vote_count": 126
},
]
Both models from the APIs:
class Movies {
int? id;
String? title;
String? overview;
List<dynamic>? genreIds;
dynamic voteAverage;
String? posterPath;
Movies({
this.id,
this.title,
this.overview,
this.genreIds,
this.voteAverage,
this.posterPath,
});
Movies.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
overview = json['overview'];
genreIds = json['genre_ids'].toList();
voteAverage = json['vote_average'];
posterPath = json['poster_path'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = id;
data['title'] = title;
data['overview'] = overview;
data['vote_average'] = voteAverage;
data['genre_ids'] = genreIds;
data['poster_path'] = posterPath;
return data;
}
}
class Genres {
int? id;
String? name;
Genres({
this.id,
this.name,
});
Genres.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'] as String;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = id;
data['name'] = name;
return data;
}
}
API calls:
Future<List<Movies?>> getAllMovies() async {
Response response = await Dio().get(Contants().moviesUrl);
return (response.data['results'] as List).map((movies) {
return Movies.fromJson(genres);
}).toList();
}
Future<List<Genres?>> getAllGenres() async {
Response response = await Dio().get(Contants().genresUrl);
return (response.data['genres'] as List).map((genres) {
return Genres.fromJson(genres);
}).toList();
}
Future builder:
FutureBuilder(
future: Future.wait([
RepositoryFromAPItoDB().gettAllMovies(),
RepositoryFromAPItoDB().getAllGenres()
]),
builder:
(BuildContext context, AsyncSnapshot<List<dynamic>?> snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
itemCount: snapshot.data?[0].length,
itemBuilder: (BuildContext context, int index) {
return MoviesListTile(
title: snapshot.data?[0][index].title,
voteAverage: snapshot.data?[0][index].voteAverage,
description: snapshot.data?[0][index].overview,
posterPath: snapshot.data?[0][index].posterPath,
genreIds: snapshot.data?[0][index].genreIds,
genres: ['drama', 'somehting'],
);
},
);
}
},
),
Requested output of names from the list:
Widget getTextWidgets(List<String?> strings) {
return Row(
children: strings
.map((item) => Container(
child: Text(
item!,
),
),
),
)
.toList());
}
Any form of help is appreciated.
Is this what you wanted?
void main() {
Map<String, dynamic> genres = {
"genres": [
{"id": 28, "name": "Action"},
{"id": 12, "name": "Adventure"},
{"id": 16, "name": "Animation"},
{"id": 35, "name": "Comedy"},
{"id": 10749, "name": "Romance"},
{"id": 878, "name": "Science Fiction"},
]
};
Map<String, dynamic> movie = {
"adult": false,
"genre_ids": [16, 878, 28],
"id": 610150,
"release_date": "2022-06-11",
"title": "Dragon Ball Super: Super Hero",
"vote_average": 7.5,
"vote_count": 126
};
print(getGenres(movie, genres["genres"]));
}
List getGenres(Map movie, List genres) {
final Set movieGenreIds = Set.from(movie["genre_ids"]);
return genres
.where((g) => movieGenreIds.contains(g["id"]))
.map((g) => g["name"])
.toList();
}
The output:
[Action, Animation, Science Fiction]
Edit, using the models you provided.
List getGenres(Movie movie, List<Genre> genres) {
final Set movieGenreIds = Set.from(movie.genreIds);
return genres
.where((g) => movieGenreIds.contains(g.id))
.map((g) => g.name)
.toList();
}
I've been trying to get a column from a array into a list, I'm can't seem to figure how to do it, and I couldn't find a solution online. Most of the array i find only aren't nested.
{
"status": true,
"data": {
"1": [
{
"id": "1",
"name": "500MB [SME]",
"price": "220",
"telco_price": "0"
},
{
"id": "2",
"name": "1GB [SME]",
"price": "410",
"telco_price": "0"
},
{
"id": "3",
"name": "2GB [SME]",
"price": "800",
"telco_price": "0"
},
],
"2": [
{
"id": "AIR1000",
"name": "1.5GB ",
"price": "920",
"telco_price": "920"
},
{
"id": "AIR2000",
"name": "4.5GB",
"price": "1840",
"telco_price": "1840"
},
{
"id": "AIR2500",
"name": "6GB",
"price": "2300",
"telco_price": "2300"
}
],
"3": [
{
"id": "9MOB500",
"name": "500MB",
"price": "400",
"telco_price": "400"
},
{
"id": "9MOB1000",
"name": "1.5GB",
"price": "850",
"telco_price": "850"
},
{
"id": "9MOB2000",
"name": "2GB",
"price": "1020",
"telco_price": "1020"
},
]
}
}
firstly, i want to get all names into a list variable which i can then populate easily on one of my page...
i want it into var nameList = []; where its' stated "1" then the next into another variable like that
Do on fetch like
import 'package:http/http.dart' as http;
....
List<DataClass> nameList = [];
fetch() async {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
MyResponse myResponse = MyResponse.fromJson(data);
final values = myResponse.data?.values;
if (values != null) {
for (final v in values) {
if(v!=null) nameList.addAll(v.toList());
}
}
}
}
Try this model class
import 'dart:convert';
class MyResponse {
final bool? status;
final Map<String, List<DataClass>?>? data;
MyResponse({
this.status,
required this.data,
});
Map<String, dynamic> toMap() {
final result = <String, dynamic>{};
if(status != null){
result.addAll({'status': status});
}
if(data != null){
result.addAll({'data': data});
}
return result;
}
factory MyResponse.fromMap(Map<String, dynamic> map) {
return MyResponse(
status: map['status'],
data: Map<String, List<DataClass>?>.from(map['data']),
);
}
String toJson() => json.encode(toMap());
factory MyResponse.fromJson(String source) => MyResponse.fromMap(json.decode(source));
}
class DataClass {
final String? id;
final String? name;
final String? price;
final String? telco_price;
DataClass({
this.id,
this.name,
this.price,
this.telco_price,
});
Map<String, dynamic> toMap() {
final result = <String, dynamic>{};
if (id != null) {
result.addAll({'id': id});
}
if (name != null) {
result.addAll({'name': name});
}
if (price != null) {
result.addAll({'price': price});
}
if (telco_price != null) {
result.addAll({'telco_price': telco_price});
}
return result;
}
factory DataClass.fromMap(Map<String, dynamic> map) {
return DataClass(
id: map['id'],
name: map['name'],
price: map['price'],
telco_price: map['telco_price'],
);
}
String toJson() => json.encode(toMap());
factory DataClass.fromJson(String source) =>
DataClass.fromMap(json.decode(source));
}
I am trying to map a json list in my application using JSON Serializable. But I am not able to map it.
Following is the response from the API:
{
"code": 200,
"message": "Countries Lists",
"count": 250,
"data": [
{
"id": 1,
"name": "Afghanistan"
},
{
"id": 2,
"name": "Aland Islands"
},
{
"id": 3,
"name": "Albania"
},
{
"id": 4,
"name": "Algeria"
},
{
"id": 5,
"name": "American Samoa"
},
{
"id": 6,
"name": "Andorra"
},
{
"id": 7,
"name": "Angola"
},
{
"id": 8,
"name": "Anguilla"
},
{
"id": 9,
"name": "Antarctica"
},
{
"id": 10,
"name": "Antigua And Barbuda"
},
{
"id": 11,
"name": "Argentina"
},
{
"id": 12,
"name": "Armenia"
},
{
"id": 13,
"name": "Aruba"
},
{
"id": 14,
"name": "Australia"
},
{
"id": 15,
"name": "Austria"
},
{
"id": 16,
"name": "Azerbaijan"
},
{
"id": 17,
"name": "Bahamas The"
},
{
"id": 18,
"name": "Bahrain"
},
{
"id": 19,
"name": "Bangladesh"
},
{
"id": 20,
"name": "Barbados"
}
]
}
Following is my response file:
#JsonSerializable()
class BaseResponse {
#JsonKey(name: "code")
int? status;
#JsonKey(name: "message")
String? message;
}
#JsonSerializable(explicitToJson: true)
class AllCountryResponse extends BaseResponse {
#JsonKey(name: "data")
List<CountryResponse> data;
AllCountryResponse(this.data);
//from JSON
factory AllCountryResponse.fromJson(Map<String, dynamic> json) =>
_$AllCountryResponseFromJson(json);
//to JSON
Map<String, dynamic> toJson() => _$AllCountryResponseToJson(this);
}
#JsonSerializable()
class CountryResponse {
#JsonKey(name: "id")
String? id;
#JsonKey(name: "name")
String? name;
CountryResponse(this.id, this.name);
//from JSON
factory CountryResponse.fromJson(Map<String, dynamic> json) =>
_$CountryResponseFromJson(json);
//to JSON
Map<String, dynamic> toJson() => _$CountryResponseToJson(this);
}
I am able to generate the responses.g dart file.
Following is my mapper class file:
class Countries {
String id,name;
Countries(this.id,this.name);
}
class AllCountries{
List<Countries> countries;
AllCountries(this.countries);
}
extension CountryResponseMapper on CountryResponse? {
Countries toDomain() {
return Countries(
this?.id.orEmpty() ?? EMPTY, this?.name.orEmpty() ?? EMPTY);
}
}
extension AllCountriesResponseMapper on AllCountryResponse? {
AllCountries toDomain() {
return AllCountries(this?.data.map((e) => e.toDomain()).toList() ?? []);
}
}
Once I run my api I do get 200 status while using my bio, but after that it shows me the default error I have set, i.e. "Something went wrong". Which means there is an issue in mapping the response.
Can someone help me with mapping this list please?
This code should work.
This code is generated by a very small and simple script (which was written in a few minutes).
class Response {
Response(
{required this.code,
required this.message,
required this.count,
required this.data});
factory Response.fromJson(Map json) {
return Response(
code: json['code'] as int?,
message: json['message'] as String?,
count: json['count'] as int?,
data: json['data'] == null
? []
: (json['data'] as List).map((e) => Data.fromJson(e as Map)).toList(),
);
}
final int? code;
final String? message;
final int? count;
final List<Data> data;
static List<Response> fromJsonList(List json) {
return json.map((e) => Response.fromJson(e as Map)).toList();
}
Map<String, dynamic> toJson() {
return {
'code': code,
'message': message,
'count': count,
'data': data.map((e) => e.toJson()).toList(),
};
}
static List<Map<String, dynamic>> toJsonList(List<Response> list) {
return list.map((e) => e.toJson()).toList();
}
}
class Data {
Data({required this.id, required this.name});
factory Data.fromJson(Map json) {
return Data(
id: json['id'] == null ? 0 : json['id'] as int,
name: json['name'] == null ? '' : json['name'] as String,
);
}
final int id;
final String name;
static List<Data> fromJsonList(List json) {
return json.map((e) => Data.fromJson(e as Map)).toList();
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
};
}
static List<Map<String, dynamic>> toJsonList(List<Data> list) {
return list.map((e) => e.toJson()).toList();
}
}
Code generation script:
import 'dart:io';
import 'package:object_serializer/json_serializer_generator.dart';
import 'package:yaml/yaml.dart';
void main() {
final classes = loadYaml(_classes) as Map;
final g = JsonSerializerGenerator();
final classesCode = g.generateClasses(classes);
final values = {
'classes': classesCode,
};
var source = g.render(_template, values);
source = g.format(source);
File('bin/stackoverflow.dart').writeAsStringSync(source);
}
const _classes = r'''
Response:
fields:
code: int?
message: String?
count: int?
data: List<Data>
Data:
fields:
id: int
name: String
''';
const _template = r'''
{{classes}}
''';
I have a Map which stores an API response that I intend to use throughout my Application. Although, the API part works just as I expected, the trouble begins when I try displaying the total amount of all the objects. The total amount needs to be calculated in the following way:total += product_selling_price * quantity;.
However, the logic that I have written throws the below error:
Class 'int' has no instance method '[]'.
Receiver: 0
Tried calling: []("product_selling_price")
The JSON response, the method that calculates the total and the widget from which the method is called are as follows. Also, I will mark the lines where the errors are pointed at.
The JSON response:
{
"status": "success",
"data": [
{
"cart_id": 18,
"restaurant_id": "1",
"product_id": "5",
"restaurant_name": "City Club",
"product_name": "Palak Paneer",
"product_description": "Tasty silky gravy with goodness of palak",
"product_image": "/public/assets/product/C6pGz101-42-17.jpg",
"product_selling_price": "180",
"product_status": "active",
"product_quantity": "32",
"quantity": "2"
},
{
"cart_id": 17,
"restaurant_id": "1",
"product_id": "6",
"restaurant_name": "City Club",
"product_name": "Jersey Burger",
"product_description": "Tasty yummy burgir. BURGIRRRRR",
"product_image": "/public/assets/product/1Xf0sr01-43-20.jpg",
"product_selling_price": "185",
"product_status": "active",
"product_quantity": "50",
"quantity": "2"
},
{
"cart_id": 16,
"restaurant_id": "1",
"product_id": "7",
"restaurant_name": "City Club",
"product_name": "Tibetan Soup",
"product_description": "Healthy Soup from the mountains of Tibet",
"product_image": "/public/assets/product/CgMBpm02-03-38.jpg",
"product_selling_price": "120",
"product_status": "active",
"product_quantity": "24",
"quantity": "2"
}
]
}
The class with the method:
class CartItemProvider with ChangeNotifier {
Map<String, dynamic> _cartItems = {};
List<dynamic> _individualItems = [];
Network network = Network();
String baseUrl = 'https://achievexsolutions.in/current_work/eatiano/';
double deliveryCost = 40;
double discountCost = 50;
List<dynamic> get cartItemList {
return [..._cartItemList];
}
Map<String, dynamic> get cartItems {
return {..._cartItems};
}
Future<void> fetchCartItems() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
final url = Uri.parse(baseUrl + 'api/auth/cart');
final response = await http.get(url, headers: {
'Authorization': 'Bearer ${localStorage.getString('token')}',
'Accept': 'application/json'
});
Cart cartJson = cartFromJson(response.body);
_cartItems = cartJson.toJson();
print('Cart Item $_cartItems');
}
double get itemAmount { //The method in question
double total = 0.0;
total = _cartItems['data'].fold( //The above error gets pointed from this line
0,
(price, value) =>
price +
(double.parse(price['product_selling_price']) * //To This line, at price['product_selling_price']
double.parse(price['quantity'])));
return total;
}
}
The Model Class in case someone needs to take a look:
import 'package:meta/meta.dart';
import 'dart:convert';
Cart cartFromJson(String str) => Cart.fromJson(json.decode(str));
String cartToJson(Cart data) => json.encode(data.toJson());
class Cart {
Cart({
required this.status,
required this.data,
});
final String status;
final List<Datum> data;
factory Cart.fromJson(Map<String, dynamic> json) => Cart(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
required this.cartId,
required this.restaurantId,
required this.productId,
required this.restaurantName,
required this.productName,
required this.productDescription,
required this.productImage,
required this.productSellingPrice,
required this.productStatus,
required this.productQuantity,
required this.quantity,
});
final int cartId;
final String restaurantId;
final String productId;
final String restaurantName;
final String productName;
final String productDescription;
final String productImage;
final String productSellingPrice;
final String productStatus;
final String productQuantity;
final String quantity;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
cartId: json["cart_id"],
restaurantId: json["restaurant_id"],
productId: json["product_id"],
restaurantName: json["restaurant_name"],
productName: json["product_name"],
productDescription: json["product_description"],
productImage: json["product_image"],
productSellingPrice: json["product_selling_price"],
productStatus: json["product_status"],
productQuantity: json["product_quantity"],
quantity: json["quantity"],
);
Map<String, dynamic> toJson() => {
"cart_id": cartId,
"restaurant_id": restaurantId,
"product_id": productId,
"restaurant_name": restaurantName,
"product_name": productName,
"product_description": productDescription,
"product_image": productImage,
"product_selling_price": productSellingPrice,
"product_status": productStatus,
"product_quantity": productQuantity,
"quantity": quantity,
};
}
The widget from which the itemAmount getter is called:
class CartDetailScreen extends StatefulWidget {
CartDetailScreenState createState() => CartDetailScreenState();
}
class CartDetailScreenState extends State<CartDetailScreen> {
#override
Widget build(BuildContext context) {
......
// TODO: implement build
return Scaffold(
......
body: ListView(
children: [
........
),
Text(
'₹ ${Provider.of<CartItemProvider>(context).itemAmount //This is where the itemAmount method is accessed from
}',
........
],
));
}
}
I would like to know what I need to do to fix and get rid of this error.
fold function is a reducer, first argument (you name it price) is the precedent value so it is an int not an array of int and second value (you name it value) is the current value.
So you can't use price[...] if current value is an array use value[...]
https://api.dart.dev/stable/1.10.1/dart-core/List/fold.html
Your code should be like this:
double get itemAmount {
double total = 0.0;
total = _cartItems['data'].fold(
0,
(price, value) =>
price +
(double.parse(value['product_selling_price']) *
double.parse(value['quantity'])));
return total;
}
I want to get data from API, my API data as DoctorModel inside it daysModel, inside daysModel is workTimeModel, each doctor has many days and has worktime.
I tried a lot of ways but still can't fix it.
note: I made my API from this website https://app.quicktype.io/
my code to get API data:
Response res = await get(
doctorsUrl ,
);
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
List<dynamic> data = body['data'];
List<DoctorInfoModel> doctors = data.map((dynamic item) => DoctorInfoModel.fromJson(item)).toList();
return doctors;
}
my API:
{
"id": 15,
"name": "Prof. Elton Quigley",
"about": "uHiKeKA1gq",
"stars": 5,
"location": "R59lmj1eud",
"latitude": 5,
"longitude": 5,
"notes": "yCl95VqUAz",
"days": [
{
"name": "سبت",
"pivot": {
"doctor_id": 15,
"day_id": 1,
"morning": "1",
"evening": "1"
}
},
{
"name": "أحد",
"pivot": {
"doctor_id": 15,
"day_id": 2,
"morning": "3",
"evening": "3"
}
},
{
"name": "إثنين",
"pivot": {
"doctor_id": 15,
"day_id": 3,
"morning": "5",
"evening": "5"
}
},
{
"name": "ثلاثاء",
"pivot": {
"doctor_id": 15,
"day_id": 4,
"morning": "4",
"evening": "4"
}
},
{
"name": "أربعاء",
"pivot": {
"doctor_id": 15,
"day_id": 5,
"morning": "5",
"evening": "5"
}
},
{
"name": "خميس",
"pivot": {
"doctor_id": 15,
"day_id": 6,
"morning": "4",
"evening": "4"
}
}
]
}
my DoctorModel:
// To parse this JSON data, do
//
// final doctorInfoModel = doctorInfoModelFromJson(jsonString);
import 'dart:convert';
DoctorInfoModel doctorInfoModelFromJson(String str) => DoctorInfoModel.fromJson(json.decode(str));
String doctorInfoModelToJson(DoctorInfoModel data) => json.encode(data.toJson());
class DoctorInfoModel {
DoctorInfoModel({
this.id,
this.name,
this.about,
this.stars,
this.location,
this.latitude,
this.longitude,
this.notes,
this.days,
});
int id;
String name;
String about;
int stars;
String location;
int latitude;
int longitude;
String notes;
List<Day> days;
factory DoctorInfoModel.fromJson(Map<String, dynamic> json) => DoctorInfoModel(
id: json["id"],
name: json["name"],
about: json["about"],
stars: json["stars"],
location: json["location"],
latitude: json["latitude"],
longitude: json["longitude"],
notes: json["notes"],
days: List<Day>.from(json["days"].map((x) => Day.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"about": about,
"stars": stars,
"location": location,
"latitude": latitude,
"longitude": longitude,
"notes": notes,
"days": List<dynamic>.from(days.map((x) => x.toJson())),
};
}
class Day {
Day({
this.name,
this.pivot,
});
String name;
Pivot pivot;
factory Day.fromJson(Map<String, dynamic> json) => Day(
name: json["name"],
pivot: Pivot.fromJson(json["pivot"]),
);
Map<String, dynamic> toJson() => {
"name": name,
"pivot": pivot.toJson(),
};
}
class Pivot {
Pivot({
this.doctorId,
this.dayId,
this.morning,
this.evening,
});
int doctorId;
int dayId;
String morning;
String evening;
factory Pivot.fromJson(Map<String, dynamic> json) => Pivot(
doctorId: json["doctor_id"],
dayId: json["day_id"],
morning: json["morning"],
evening: json["evening"],
);
Map<String, dynamic> toJson() => {
"doctor_id": doctorId,
"day_id": dayId,
"morning": morning,
"evening": evening,
};
}
How can I get data correctly?
I figured out how to get data.
I replaced these two lines:
List<dynamic> data = body['data'];
List<DoctorInfoModel> doctors = data.map((dynamic item) => DoctorInfoModel.fromJson(item)).toList();
by these:
var data = body['data'];
DoctorInfoModel doctorInfo = DoctorInfoModel.fromJson(data);
when my DoctorInfoModel is not a List, so I delete it.
Correct code to get API data:
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
var data = body['data'];
DoctorInfoModel doctorInfo = DoctorInfoModel.fromJson(data);
print(doctorInfo.name);
print(doctorInfo.about);
print(doctorInfo.days[0].name);
print(doctorInfo.days[0].pivot.morning);
return doctorInfo;
}