cast in model not working wit getX flutter - flutter

I have an application with news api from https://newsapi.org/
My model from quicktype:
// To parse this JSON data, do
//
// final news = newsFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
List<News> newsFromJson(String str) =>
List<News>.from(json.decode(str).map((x) => News.fromJson(x)));
String newsToJson(List<News> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class News {
News({
required this.status,
required this.totalResults,
required this.articles,
});
final String status;
final int totalResults;
final List<Article> articles;
factory News.fromJson(Map<String, dynamic> json) => News(
status: json["status"],
totalResults: json["totalResults"],
articles: List<Article>.from(
json["articles"].map((x) => Article.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"totalResults": totalResults,
"articles": List<dynamic>.from(articles.map((x) => x.toJson())),
};
}
class Article {
Article({
required this.source,
required this.author,
required this.title,
required this.description,
required this.url,
required this.urlToImage,
required this.publishedAt,
required this.content,
});
final Source source;
final String author;
final String title;
final String description;
final String url;
final String urlToImage;
final DateTime publishedAt;
final String content;
factory Article.fromJson(Map<String, dynamic> json) => Article(
source: Source.fromJson(json["source"]),
author: json["author"] == null ? null : json["author"],
title: json["title"],
description: json["description"],
url: json["url"],
urlToImage: json["urlToImage"],
publishedAt: DateTime.parse(json["publishedAt"]),
content: json["content"],
);
Map<String, dynamic> toJson() => {
"source": source.toJson(),
"author": author == null ? null : author,
"title": title,
"description": description,
"url": url,
"urlToImage": urlToImage,
"publishedAt": publishedAt.toIso8601String(),
"content": content,
};
}
class Source {
Source({
required this.id,
required this.name,
});
final String id;
final String name;
factory Source.fromJson(Map<String, dynamic> json) => Source(
id: json["id"] == null ? null : json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
"name": name,
};
}
In my remoteservice.dart:
import 'package:http/http.dart' as http;
import 'package:nocovid/models/news.dart';
import 'package:nocovid/utils/constant.dart';
class RemoteServices {
static var client = http.Client();
static Future<List<News>?> fetchNews() async {
final String endpoint =
'https://newsapi.org/v2/everything?q=covid19&apiKey=' + kAPIKey;
final Uri url = Uri.parse(endpoint);
final response = await client.get(url);
if (response.statusCode == 200) {
var jsonString = response.body;
return newsFromJson(jsonString);
} else {
return null;
}
}
}
newscontroller.dart
import 'package:get/state_manager.dart';
import 'package:nocovid/models/news.dart';
import 'package:nocovid/services/remote_services.dart';
class NewsController extends GetxController {
var newsList = <News>[].obs;
#override
void onInit() {
fetchNews();
super.onInit();
}
void fetchNews() async {
var news = await RemoteServices.fetchNews();
if (news != null) {
newsList.value = news;
}
}
}
And get this errors:
and
the call is performed regularly but upon showing the data, it generates these errors.
I checked some codes on github and everything seems to work, while i can't get going

Change
List<News> newsFromJson(String str) =>
List<News>.from(json.decode(str).map((x) => News.fromJson(x)));
To
News newsFromJson(String str) => News.fromJson(json.decode(str));
The Reason for this is News object is not a list, it's a complex JSON with a map that consists of a list of Articles. You need to go through API properly.
If you want a model you can use quicktype. Just paste in the URL response.
Also Change
static Future<List<News>?> fetchNews()
to
static Future<News> fetchNews()

Related

Flutter Future Filtered Data

I'm pulling my data from MongoDB with a Future. However, I want to pull only some of the data, not the whole data. How can I filter this?
I will put the data I filtered into the list. I added the readMongo and lessonModel codes.
In addition, although my codes work very well, I think that I did not do something according to the rules, if I am missing, I would be very happy if you could point out.
Future<List<Map<String, dynamic>>> _getData() async {
values = MongoDatabase.readMongo(MongoDatabase.lessonCollection);
return values!;
}
readMongo
static Future<List<Map<String, dynamic>>> readMongo(collectionName) async {
final data = await collectionName.find().toList();
return data;
}
LessonModel
import 'dart:convert';
LessonModel lessonModelFromMap(String str) => LessonModel.fromMap(json.decode(str));
String lessonModelToMap(LessonModel data) => json.encode(data.toMap());
class LessonModel {
LessonModel({this.id, this.info, this.subject});
final Id? id;
final Info? info;
final List<Subject>? subject;
factory LessonModel.fromMap(Map<String, dynamic> json) => LessonModel(
info: json["info"] == null ? null : Info.fromMap(json["info"]),
subject: json["subject"] == null ? null : List<Subject>.from(json["subject"].map((x) => Subject.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"_id": id == null ? null : id!.toMap(),
"info": info == null ? null : info!.toMap(),
"subject": subject == null ? null : List<dynamic>.from(subject!.map((x) => x.toMap())),
};
}
class Id {
Id({this.oid});
final String? oid;
factory Id.fromMap(Map<String, dynamic> json) => Id(oid: json["\u0024oid"]);
Map<String, dynamic> toMap() => {"\u0024oid": oid};
}
class Info {
Info({this.name, this.infoClass, this.semester, this.credit, this.icon});
final String? name;
final String? infoClass;
final String? semester;
final int? credit;
final String? icon;
factory Info.fromMap(Map<String, dynamic> json) => Info(
name: json["name"],
infoClass: json["class"],
semester: json["semester"],
credit: json["credit"],
icon: json["icon"]);
Map<String, dynamic> toMap() =>
{"name": name, "class": infoClass, "semester": semester, "credit": credit, "icon": icon};
}
class Subject {
Subject({this.subjectId, this.name, this.text, this.video, this.trainer});
final int? subjectId;
final String? name;
final String? text;
final String? video;
final String? trainer;
factory Subject.fromMap(Map<String, dynamic> json) => Subject(
subjectId: json["subjectId"],
name: json["name"],
text: json["text"],
video: json["video"],
trainer: json["trainer"]);
Map<String, dynamic> toMap() =>
{"subjectId": subjectId, "name": name, "text": text, "video": video, "trainer": trainer};
}

A value of type 'Iterable<HospitalListModel>' can't be assigned to a variable of type 'List<HospitalListModel>'

I got a flutter error A value of type 'Iterable<HospitalListModel>' can't be assigned to a variable of type 'List<HospitalListModel>'. This is my model:
List<HospitalListModel> hospitalListModelFromJson(String str) => List<HospitalListModel>.from(json.decode(str).map((x) => HospitalListModel.fromJson(x)));
String hospitalListModelToJson(List<HospitalListModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class HospitalListModel {
HospitalListModel({
this.id,
this.title,
this.content,
this.image,
this.phone,
this.coordinates,
this.website,
this.createdAt,
this.updatedAt,
});
dynamic id;
dynamic title;
dynamic content;
dynamic image;
dynamic phone;
dynamic coordinates;
dynamic website;
dynamic createdAt;
dynamic updatedAt;
factory HospitalListModel.fromJson(Map<String, dynamic> json) => HospitalListModel(
id: json["id"],
title: json["title"],
content: json["content"],
image: json["image"],
phone: json["phone"],
coordinates: json["coordinates"],
website: json["website"],
createdAt: json["created_at"],
updatedAt: json["updated_at"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"content": content,
"image": image,
"phone": phone,
"coordinates": coordinates,
"website": website,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
and this is where the error come from, it's from the API provider and im confused why it throw iterable
class ApiProvider {
final Dio _dio = Dio();
final String _url = 'http://lovemonster.my.id/hospital';
Future<List<HospitalListModel>> fetchHospitalList() async {
try {
List<HospitalListModel> hospitalList = [];
Response response = await _dio.get(_url);
var mData = response.data as List;
hospitalList = mData.
map<HospitalListModel>((e) => hospitalListModelFromJson(e)
.toList();
return hospitalList;//return List not object
} catch (error, stacktrace) {
print("Exception occurred: $error stackTrace: $stacktrace");
return Future.error("");
}
}
}
hospitalList = mData.map<HospitalListModel>((e) =>hospitalListModelFromJson(e).toList();this code throw an error, and if you wondering how the other class or method, i will put event & state that seems related to the error:
state:
abstract class HospitalListState extends Equatable {
const HospitalListState();
#override
List<Object?> get props => [];
}
class HospitalListInitial extends HospitalListState {}
class HospitalListLoading extends HospitalListState {}
class HospitalListLoaded extends HospitalListState {
final List<HospitalListModel> hospitalListModel;
const HospitalListLoaded(this.hospitalListModel);
}
class HospitalListError extends HospitalListState {
final String? message;
const HospitalListError(this.message);
}
event:
abstract class HospitalListEvent extends Equatable {
const HospitalListEvent();
#override
List<Object> get props => [];
}
class GetCovidList extends HospitalListEvent {}
i made this code with flutter_bloc and if you want to know more details just let me know, and if you know what's wrong with my code, just type it on the answer, i appreciate every answers and knowledge that you share with me
You have missed ')' before using toList method you have close the map method.
hospitalList = mData.map<HospitalListModel>((e) => hospitalListModelFromJson(e))
.toList();

Flutter Unhandled Exception: type 'Null' is not a subtype of type 'Response<AuthResponse>' in type cast

I can't seem to figure out the issue in my flutter GetConnect request, I am using the Getx's Getconnect library to send an API request to authenticate users, the requests are authenticated successfully but then the app throws an error when I try to get the user data and token back,
class AuthService {
final IHttpConnect _connect;
const AuthService(IHttpConnect connect) : _connect = connect;
String get _prefix => 'auth';
Future<AuthResponse> authenticateUser(
var body,
) async {
final response = await _connect.post(
'$_prefix/login',
body,
decoder: (value){
print(value);
AuthResponse data = AuthResponse.fromJson(
value as Map<String, dynamic>,
);
return data;
},
);
if (response.success) {
return response.payload!;
} else {
switch (response.statusCode) {
case 404:
throw UserNotFoundException();
default:
throw DefaultException(message: response.payload!.error!);
}
}
}
}
My AuthResponse model looks like this
import 'package:json_annotation/json_annotation.dart';
part 'auth_response.g.dart';
#JsonSerializable()
class AuthResponse {
AuthResponse({
required this.success,
this.data,
this.error,
});
final bool success;
final Data? data;
final String? error;
factory AuthResponse.fromJson(Map<String, dynamic> json) => _$AuthResponseFromJson(json);
Map<String, dynamic> toJson() => _$AuthResponseToJson(this);
}
#JsonSerializable()
class Data {
Data({
required this.token,
required this.user,
});
final String token;
final User user;
factory Data.fromJson(Map<String, dynamic> json) => _$DataFromJson(json);
Map<String, dynamic> toJson() => _$DataToJson(this);
}
#JsonSerializable()
class User {
User({
required this.id,
required this.name,
required this.email,
required this.emailVerifiedAt,
required this.createdAt,
required this.updatedAt,
});
final int id;
final String name;
final String email;
#JsonKey(name: 'email_verified_at')
final DateTime? emailVerifiedAt;
#JsonKey(name: 'created_at')
final DateTime createdAt;
#JsonKey(name: 'updated_at')
final DateTime updatedAt;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
If I print the data I get
{success: true, data: {token: 157|4YXMdrMwDIECxsVSf5hIeON5scCu9lZTQP2B5wXa, user: {id: 1, name: Kenya Friesen, email: mdavis#yahoo.com, email_verified_at: 2022-11-18T00:27:42.000000Z, created_at: 2022-11-18T00:27:42.000000Z, updated_at: 2022-11-18T00:27:42.000000Z}}, error: ddd}
IHttpConnect class
import './response.model.dart';
abstract class IHttpConnect {
Future<Response<T>> get<T>(
String url, {
required T Function(dynamic)? decoder,
});
Future<Response<T>> post<T>(
String url,
Map<String, dynamic> body, {
T Function(dynamic)? decoder,
});
Future<Response<T>> put<T>(
String url,
Map<String, dynamic> body, {
T Function(dynamic)? decoder,
});
Future<Response<T>> patch<T>(
String url,
Map<String, dynamic> body, {
T Function(dynamic)? decoder,
});
Future<Response<T>> delete<T>(
String url, {
required T Function(dynamic)? decoder,
});
}
Response Class
class Response<T> {
final int statusCode;
final T? payload;
bool get success => statusCode <= 200;
const Response({
required this.statusCode,
required this.payload,
});
}
I appreciate any assistance

Save nested objects in shared preferences

I have an object that contains a json array , which am trying to store in shared preferences but i don't know how to do so .
This is my model :
import 'dart:convert';
import 'package:deepnrise/models/settings/perimeter.dart';
import 'package:deepnrise/models/user/user_perims.dart';
UserWithPerim user(String str) => UserWithPerim.fromJson(json.decode(str));
class UserWithPerim {
// ignore: non_constant_identifier_names
UserWithPerim({
required this.identifier,
required this.firstName,
required this.lastName,
required this.email,
required this.role,
required this.perimeters,
});
String identifier;
String firstName;
String lastName;
String email;
String role;
List<UserPerimeter> perimeters;
factory UserWithPerim.fromJson(Map<String, dynamic> json) {
return UserWithPerim(
identifier: json['identifier'] ?? "",
firstName: json['firstName'] ?? "",
lastName: json['lastName'] ?? "",
email: json['email'] ?? "",
role: json['role'] ?? "",
perimeters: (json['perimeters'] as List)
.map((p) => UserPerimeter.fromJson(p))
.toList(),
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['identifier'] = identifier;
data['firstName'] = firstName;
data['lastName'] = lastName;
data['role'] = role;
data['email'] = email;
data['perimeters'] = perimeters;
return data;
}
}
This the perimeters model :
import 'dart:convert';
Userperimeters(String str) => UserPerimeter.fromJson(json.decode(str));
String UserPerimToJson(UserPerimeter data) => json.encode(data.tojson());
class UserPerimeter {
// ignore: non_constant_identifier_names
UserPerimeter(
{required this.id, required this.label, required this.perimeterId});
// ignore: non_constant_identifier_names
int id;
String label;
int perimeterId;
factory UserPerimeter.fromJson(Map<String, dynamic> json) {
return UserPerimeter(
id: json['id'] ?? "",
label: json['label'] ?? "",
perimeterId: json["perimeterId"] ?? "");
}
Map<String, dynamic> tojson() => {
"id": id,
"label": label,
"perimeterId": perimeterId,
};
}
For now I've two models of my user object , one that contains the perils list and one that doesn't because whenever I try to store my user in shared prefs I get this exception thrown :
Unhandled Exception: type 'UserPerimeter' is not a subtype of type 'Map<String, dynamic>'
This is how am saving and reading my user:
saveUser(value) async {
final prefs = await SharedPreferences.getInstance();
String user = jsonEncode(User.fromJson(value));
prefs.setString(Preferences.USER_KEY, user);
}
Future<User?> getUser() async {
final prefs = await SharedPreferences.getInstance();
if (prefs.containsKey(Preferences.USER_KEY)) {
Map<String, dynamic> userMap =
jsonDecode(prefs.getString(Preferences.USER_KEY) ?? "");
User user = User.fromJson(userMap);
return user;
}
}
Is there a way with which I can store the whole user model with the perils object list without making two models of the user object ? thank you so much in advance.
The work around here to convert your whole json response to string.
save that string into sharedprefs, then you can call it back and decode it using:
var response = json.decode(prefs.getString("response");
So, the full idea:
prefs.setString("response",json.encode(response.body));
using that String as json format again:
MyModel model = MyModel.fromJson(json.decode(prefs.getString("response")));
I hope you find what you need from this idea.
Convert the list of perimeters to list of Json like this:
if (this.perimeters != null) {
data['perimeters'] = this.perimeters!.map((v) => v.toJson()).toList();
}

A value of type 'Resut' can't be returned from function'fetchPromotions' because it has a return type of Future<List<Promotions>>

I am fetching some data from an API, which returns a Json array, promotions_model.dart does all the parsing, but this error is showing up.
Error--
A value of type 'Result' can't be returned from function 'fetchPromotions' because it has a return type of 'Future<List>'.
can someone please tell me what i am doing wrong here. thanks
**promotions_model.dart**
import 'dart:convert';
Result resultFromJson(String str) => Result.fromJson(json.decode(str));
String resultToJson(Result data) => json.encode(data.toJson());
class Result {
Result({
this.code,
this.result,
});
final int code;
final List<Promotions> result;
factory Result.fromJson(Map<String, dynamic> json) => Result(
code: json["Code"],
result: List<Promotions>.from(
json["Result"].map((x) => Promotions.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Code": code,
"Result": List<dynamic>.from(result.map((x) => x.toJson())),
};
}
class Promotions {
Promotions({
this.id,
this.title,
this.description,
this.image,
});
final String id;
final String title;
final String description;
final String image;
factory Promotions.fromJson(Map<String, dynamic> json) => Promotions(
id: json["id"],
title: json["title"],
description: json["description"],
image: json["image"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"description": description,
"image": image,
};
}
**promotion-api.dart**
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:project/models/promotions_model.dart';
const key = {
'APP-X-RESTAPI-KEY': "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
};
const API = 'http://111.111.11.1/project';
Future<List<Promotions>> fetchPromotions() async {
final response = await http.get(API + '/promotion/all', headers: key);
if (response.statusCode == 200) {
return resultFromJson(response.body); // This line is causing the error
} else {
print(response.statusCode);
}
}
The Error says it clearly. It needs Result as the return type.
You can something like this,
Result fetchPromotions() async {
final response = await http.get(API + '/promotion/all', headers: key);
Result result = null;
if (response.statusCode == 200) {
result = resultFromJson(response.body); // This line is causing the error
} else {
print(response.statusCode);
}
return result;
}
Hope you got an idea.
return resultFromJson(response.body);
This line returns a Result, not a List<Promotion>.