Parsing Json from Api in flutter - flutter

I am having this type of response from API
{
"success": 1,
"data": [
{
"id": 539,
"user_id": 3115,
"amount": 5788,
"payment_gateway": "bank",
"message": "chchhb",
"status": "waiting",
"source": "everyone",
"created_ts": "2019-12-19 13:41:17",
"processed_ts": null
},
]
}
this is my model.dart
class Model {
final String status;
final List<String> data;
Model({
this.status,
this.data
});
factory Model.fromJson(Map<String, dynamic> parsedJson) {
var data = parsedJson['data'];
List<String> dataList = data.cast<String>();
return Model(
status: parsedJson['status'],
data: dataList
);
}
}
This is how I am fetching data from the model
Future<List<String>> getWithdrawals() async {
final userModel = Provider.of<UserModel>(context);
var userId = userModel.user.id;
Map<String, String> requestHeaders = {'Content-type': 'application/json'};
var body = {
'id': userId,
};
final response = await http.post(url);
if (response.statusCode == 200){
var jsonresponse = json.decode(response.body);
var withdrawals = WithdrawalModel.fromJson(jsonresponse);
return withdrawals.data;
} else {
print("Error" + response.body);
return null;
}
}
I am not able to display the data on the screen It is giving me an error like
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in typecast
In FutureBuilder<List> I am not able to get data
I don't know where I am doing a mistake Please help...

I think your response type is not correct currently it's List<String> but it should be like List<Details> and you need to create another model class named Details (Or you can change the name).
You just put your response here. It will generate dart class models for you.
NOTE: you have to remove extra comma from your response to use model generator then your response will be like.
{
"success": 1,
"data": [
{
"id": 539,
"user_id": 3115,
"amount": 5788,
"payment_gateway": "bank",
"message": "chchhb",
"status": "waiting",
"source": "everyone",
"created_ts": "2019-12-19 13:41:17",
"processed_ts": null
}
]
}
Edit:
For example in your above model just change List type string to Details(Model) and vise-versa :
class Model {
final String status;
final List<Details> data; // Update string with model
}

Try this method
Future <PaymentReply> getPayment() async {
final userModel = Provider.of<UserModel>(context);
var userId = userModel.user.id;
try {
final response = await http.post(url,
headers: {
HttpHeaders.contentTypeHeader: "application/json"
},
body: '{\'id\':\''+ userId+'\'}', // You are not sending body in your code so check if it needs to be sent.
);
print(response.body); //CHECK IF THIS IS CORRECT RESPONSE AS EXPECTED
PaymentReply reply = paymentReplyFromJson(response.body);
return reply;
}on Exception catch (e){
print(e);
return PaymentReply();
}
}
with my modal
// To parse this JSON data, do
//
// final paymentReply = paymentReplyFromJson(jsonString);
import 'dart:convert';
PaymentReply paymentReplyFromJson(String str) => PaymentReply.fromJson(json.decode(str));
String paymentReplyToJson(PaymentReply data) => json.encode(data.toJson());
class PaymentReply {
int success;
List<Datum> data;
PaymentReply({
this.success,
this.data,
});
factory PaymentReply.fromJson(Map<String, dynamic> json) => PaymentReply(
success: json["success"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
int id;
int userId;
int amount;
String paymentGateway;
String message;
String status;
String source;
String createdTs;
String processedTs;
Datum({
this.id,
this.userId,
this.amount,
this.paymentGateway,
this.message,
this.status,
this.source,
this.createdTs,
this.processedTs,
});
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
userId: json["user_id"],
amount: json["amount"],
paymentGateway: json["payment_gateway"],
message: json["message"],
status: json["status"],
source: json["source"],
createdTs: json["created_ts"],
processedTs: json["processed_ts"],
);
Map<String, dynamic> toJson() => {
"id": id,
"user_id": userId,
"amount": amount,
"payment_gateway": paymentGateway,
"message": message,
"status": status,
"source": source,
"created_ts": createdTs,
"processed_ts": processedTs,
};
}

My model was incorrect.
Solved by this model...
class WithdrawalModel {
final String status;
final String amount;
final List<Data> data;
WithdrawalModel({
this.status,
this.amount,
this.data
});
factory WithdrawalModel.fromJson(Map<String, dynamic> parsedJson) {
var list = parsedJson['data'] as List;
List<Data> dataList = list.map((i) => Data.fromJson(i)).toList();
return WithdrawalModel(
status: parsedJson['status'],
amount: parsedJson['amount'],
data: dataList
);
}
}
class Data {
int id;
int amount;
String message;
String status;
String source;
String createdTs;
Data({
this.id,
this.amount,
this.message,
this.status,
this.source,
this.createdTs
});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
amount = json['amount'];
message = json['message'];
status = json['status'];
source = json['source'];
createdTs = json['created_ts'];
}
}

Related

How to set the list of json data in flutter

I'm trying to return the items from this api https://api.maisdecristo.com/api/parents/mdcget00_parentkids/48984974812
but always the error:
Unhandled Exception: type 'List' is not a subtype of type 'Map<String, dynamic>'
this my object and model:
Future<ProdutoModel> getProduto() async {
try {
final response = await http.get(Uri.parse(
"https://api.maisdecristo.com/api/parents/mdcget00_parentkids/48984974812"));
var res = jsonDecode(response.body);
print(res);
_accountListModel = ProdutoModel.fromJson(res);
var data = res['filhos'] as List;
setState(() {
_list =
data.map<FilhoModel>((json) => FilhoModel.fromJson(json)).toList();
});
return _accountListModel;
} catch (e) {
rethrow;
}
}
class ProdutoModel {
ProdutoModel({
required this.phone,
required this.desperson,
required this.desemail,
required this.filhos,
});
final String phone;
final String desperson;
final String desemail;
final List<FilhoModel> filhos;
factory ProdutoModel.fromJson(Map<String, dynamic> json) => ProdutoModel(
phone: json["phone"],
desperson: json["desperson"],
desemail: json["desemail"],
filhos: List<FilhoModel>.from(
json["filhos"].map((x) => FilhoModel.fromJson(x))),
);
}
class FilhoModel {
FilhoModel({
required this.age,
required this.firstname,
required this.lastname,
});
final int age;
final String firstname;
final String lastname;
factory FilhoModel.fromJson(Map<String, dynamic> json) => FilhoModel(
age: json["age"],
firstname: json["firstname"],
lastname: json["lastname"],
);
}
return this api
The returned is at List, so you have to do something like:
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
final response = await http.get(Uri.parse(
"https://api.maisdecristo.com/api/parents/mdcget00_parentkids/48984974812"));
var res = jsonDecode(response.body);
print(res);
var list = res as List;
for (var item in list) {
var _accountListModel = ProdutoModel.fromJson(item); // model per item
print(_accountListModel.phone);
var data = item['filhos'] as List;
var _list =
data.map<FilhoModel>((json) => FilhoModel.fromJson(json)).toList();
print(_list);
}
}
class ProdutoModel {
ProdutoModel({
required this.phone,
required this.desperson,
required this.desemail,
required this.filhos,
});
final String phone;
final String desperson;
final String desemail;
final List<FilhoModel> filhos;
factory ProdutoModel.fromJson(Map<String, dynamic> json) => ProdutoModel(
phone: json["phone"],
desperson: json["desperson"],
desemail: json["desemail"],
filhos: List<FilhoModel>.from(
json["filhos"].map((x) => FilhoModel.fromJson(x))),
);
}
class FilhoModel {
FilhoModel({
required this.age,
required this.firstname,
required this.lastname,
});
final int age;
final String firstname;
final String lastname;
factory FilhoModel.fromJson(Map<String, dynamic> json) => FilhoModel(
age: json["age"],
firstname: json["firstname"],
lastname: json["lastname"],
);
}
[
{
"phone": "48984974812",
"desperson": "Usuario admin",
"desemail": "admin#hcode.com.br",
"filhos": [
{
"age": 7,
"firstname": "Lorenzo",
"lastname": "Chaves"
},
{
"age": 14,
"firstname": "teste",
"lastname": "acompanhante"
},
{
"age": 14,
"firstname": "meu",
"lastname": "filho"
},
{
"age": 21,
"firstname": "teste",
"lastname": "teste"
}
]
}
]
You have type conversion issue make sure the types from the api is the same as the model
you can use this website : https://app.quicktype.io
to generate model to any json file without get any erorr and it gets you functions from json and to json

why can't I call my Model in My View page?

I'm trying to learn how to use APIs, but I've been struggling to get my code to work,
here is what I have so far ;
Provider :
class MovieProvider extends GetConnect {
#override
var queryParameters = {
'limit': '8',
'genres': 'comedia',
'sort': 'year',
'type': 'movies'
};
static const String _baseUrl = 'movies-app1.p.rapidapi.com';
void onInit() {
httpClient.baseUrl = _baseUrl;
}
static const Map<String, String> _headers = {
"x-rapidapi-key": "***************",
"x-rapidapi-host": "movies-app1.p.rapidapi.com",
};
// Base API request to get response
Future<dynamic> getStats() async {
Uri uri = Uri.https(_baseUrl, '/api/movies', queryParameters);
final response = await http.get(uri, headers: _headers);
print('provider IS WORKING');
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON.
print("success");
print(response.body);
return json.decode(response.body);
} else {
print("not success");
// If that response was not OK, throw an error.
throw Exception('Failed to load json data');
}
}
}
Model :
import 'dart:convert';
Movies moviesFromJson(String str) => Movies.fromJson(json.decode(str));
String moviesToJson(Movies data) => json.encode(data.toJson());
class Movies {
Movies({
this.status,
this.success,
this.messageStatus,
this.results,
this.totalResults,
this.totalPages,
});
int? status;
bool? success;
String? messageStatus;
List<Result>? results;
int? totalResults;
int? totalPages;
factory Movies.fromJson(Map<String, dynamic> json) => Movies(
status: json["status"],
success: json["success"],
messageStatus: json["messageStatus"],
results:
List<Result>.from(json["results"].map((x) => Result.fromJson(x))),
totalResults: json["total_results"],
totalPages: json["total_pages"],
);
Map<String, dynamic> toJson() => {
"status": status,
"success": success,
"messageStatus": messageStatus,
"results": List<dynamic>.from(results!.map((x) => x.toJson())),
"total_results": totalResults,
"total_pages": totalPages,
};
}
class Result {
Result({
this.actors,
this.directors,
this.escritors,
this.otherTitles,
this.id,
this.image,
this.title,
this.rating,
this.year,
this.titleOriginal,
this.uuid,
this.description,
this.genres,
this.countries,
this.release,
this.embedUrls,
this.index,
this.episodes,
this.createdAt,
this.updatedAt,
});
List<dynamic>? actors;
List<dynamic>? directors;
List<dynamic>? escritors;
List<dynamic>? otherTitles;
String? id;
String? image;
String? title;
String? rating;
String? year;
String? titleOriginal;
String? uuid;
String? description;
List<Country>? genres;
List<Country>? countries;
String? release;
List<EmbedUrl>? embedUrls;
int? index;
List<dynamic>? episodes;
DateTime? createdAt;
DateTime? updatedAt;
factory Result.fromJson(Map<String, dynamic> json) => Result(
actors: List<dynamic>.from(json["actors"].map((x) => x)),
directors: List<dynamic>.from(json["directors"].map((x) => x)),
escritors: List<dynamic>.from(json["escritors"].map((x) => x)),
otherTitles: List<dynamic>.from(json["otherTitles"].map((x) => x)),
id: json["_id"],
image: json["image"],
title: json["title"],
rating: json["rating"],
year: json["year"],
titleOriginal: json["titleOriginal"],
uuid: json["uuid"],
description: json["description"],
genres:
List<Country>.from(json["genres"].map((x) => Country.fromJson(x))),
countries: List<Country>.from(
json["countries"].map((x) => Country.fromJson(x))),
release: json["release"],
embedUrls: List<EmbedUrl>.from(
json["embedUrls"].map((x) => EmbedUrl.fromJson(x))),
index: json["index"],
episodes: List<dynamic>.from(json["episodes"].map((x) => x)),
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
);
Map<String, dynamic> toJson() => {
"actors": List<dynamic>.from(actors!.map((x) => x)),
"directors": List<dynamic>.from(directors!.map((x) => x)),
"escritors": List<dynamic>.from(escritors!.map((x) => x)),
"otherTitles": List<dynamic>.from(otherTitles!.map((x) => x)),
"_id": id,
"image": image,
"title": title,
"rating": rating,
"year": year,
"titleOriginal": titleOriginal,
"uuid": uuid,
"description": description,
"genres": List<dynamic>.from(genres!.map((x) => x.toJson())),
"countries": List<dynamic>.from(countries!.map((x) => x.toJson())),
"release": release,
"embedUrls": List<dynamic>.from(embedUrls!.map((x) => x.toJson())),
"index": index,
"episodes": List<dynamic>.from(episodes!.map((x) => x)),
"createdAt": createdAt?.toIso8601String(),
"updatedAt": updatedAt?.toIso8601String(),
};
}
class Country {
Country({
this.name,
this.uuid,
});
String? name;
String? uuid;
factory Country.fromJson(Map<String, dynamic> json) => Country(
name: json["name"],
uuid: json["uuid"],
);
Map<String, dynamic> toJson() => {
"name": name,
"uuid": uuid,
};
}
class EmbedUrl {
EmbedUrl({
this.server,
this.url,
this.priority,
});
String? server;
String? url;
int? priority;
factory EmbedUrl.fromJson(Map<String, dynamic> json) => EmbedUrl(
server: json["server"],
url: json["url"],
priority: json["priority"],
);
Map<String, dynamic> toJson() => {
"server": server,
"url": url,
"priority": priority,
};
}
Controller :
class HomeController extends GetxController {
var m = Movies();
var r = new Result();
final provider = Get.put(MovieProvider());
final count = 0.obs;
#override
void onInit() {
provider.getStats();
super.onInit();
}
#override
void onReady() {
super.onReady();
}
#override
void onClose() {
super.onClose();
}
void increment() => count.value++;
}
And as for my View I've been so far just testing to get the title of one of the movies as a Text, using :
Text(controller.r.titleOriginal[0])
But I get an error related to Null-safety,
I tried adding a '!' in !titleOriginal, but this is what I go :
Exception has occurred.
_CastError (Null check operator used on a null value)
adding '?' doesn't work either.
Here's also my View :
class DigiappstoreView extends GetView<DigiappstoreController> {
const DigiappstoreView({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text(controller.r.titleOriginal![0])));
}
}
You are returning dynamic type from your provider. You should return a specific type. As per the code, it should return the type of Movie.
class MovieProvider extends GetConnect {
#override
var queryParameters = {
'limit': '8',
'genres': 'comedia',
'sort': 'year',
'type': 'movies'
};
static const String _baseUrl = 'movies-app1.p.rapidapi.com';
void onInit() {
httpClient.baseUrl = _baseUrl;
}
static const Map<String, String> _headers = {
"x-rapidapi-key": "***************",
"x-rapidapi-host": "movies-app1.p.rapidapi.com",
};
// Base API request to get response
Future<Movie> getStats() async {
Uri uri = Uri.https(_baseUrl, '/api/movies', queryParameters);
final response = await http.get(uri, headers: _headers);
print('provider IS WORKING');
if (response.statusCode == 200) {
return moviesFromJson(response.body);
} else {
throw Exception('Failed to load json data');
}
}
}
Also, in controller, you should assign the result to the variable like
class HomeController extends GetxController {
var m = Movies();
var r = Result();
final provider = Get.put(MovieProvider());
#override
void onInit() {
getStates();
super.onInit();
}
getStates() async {
movies = await provider.getStats();
r = movies.results;
update();
}
}
Now
in your view, wrap the child inside GetBuilder to update the UI once the data is updated.
class DigiappstoreView extends GetView<DigiappstoreController> {
const DigiappstoreView({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(body: GetBuilder<DigiappstoreController>(
init: DigiappstoreController(),
builder: (controller) {
return Center(child: Text(controller.r == null ? '' : controller.r[0].titleOriginal!));
},
));
}
}
There may be some syntax error as i have not tried the code myself but these are the updates that you need to do.
I think you need to read the GetX Documentation in detail to know how it works

Flutter - Dart parsing json data array returns type 'List<dynamic>' is not a subtype of type 'List<BusinessTest>'

I'm trying to parse a json file using a custom model, I always get the error type 'List<dynamic>' is not a subtype of type 'List<BusinessTest>' and I don't know how I can fix my code. Also is it a good idea to always use nullable type in variables when you parse json files?
This is a Json example of my data:
{
"businesses": [{
"id": "1",
"alias": "123",
"name": "aaa",
"image_url": "xxx.jpg",
"is_closed": false,
"url": ".com",
"review_count": 26,
"rating": 5.0
},
{
"id": "2",
"alias": "123",
"name": "aaa",
"image_url": "xxx.jpg",
"is_closed": false,
"url": ".com",
"review_count": 26,
"rating": 5.0
}
]
}
Here is the model code I've made in order to parse the Json:
class BusinessSearch {
final List<BusinessTest> businesses;
final int total;
BusinessSearch(this.businesses, this.total);
BusinessSearch.fromJson(Map<String, dynamic> json)
: businesses = json['businesses'],
total = json['total'];
}
class BusinessTest {
final String? name;
final String? imageUrl;
final bool? isClosed;
final String? url;
final int? reviewCount;
BusinessTest(
this.name, this.imageUrl, this.isClosed, this.url, this.reviewCount);
BusinessTest.fromJson(Map<String, dynamic> json)
: name = json['name'],
imageUrl = json['image_url'],
isClosed = json['is_closed'],
url = json['url'],
reviewCount = json['review_count'];
}
This is how I'm trying to parse it:
void getData() async {
try {
String url = 'url';
NetworkHelp network = NetworkHelp(url: url);
var data = await network.getData();
Map<String, dynamic> businessMap = await jsonDecode(data);
var business = BusinessSearch.fromJson(businessMap);
} catch (e) {
print(e);
}
}
You have to update your BusinessSearch model like this.
class BusinessSearch {
BusinessSearch({
this.businesses,
this.total,
});
List<Business> businesses = [];
int total;
factory BusinessSearch.fromJson(Map<String, dynamic> json) => BusinessSearch(
businesses: List<Business>.from(json["businesses"].map((x) => Business.fromJson(x))),
total: json['total']
);
Map<String, dynamic> toJson() => {
"businesses": List<dynamic>.from(businesses.map((x) => x.toJson())),
"total": total,
};
}
class Business {
Business({
this.id,
this.alias,
this.name,
this.imageUrl,
this.isClosed,
this.url,
this.reviewCount,
this.rating,
});
String id;
String alias;
String name;
String imageUrl;
bool isClosed;
String url;
int reviewCount;
int rating;
factory Business.fromJson(Map<String, dynamic> json) => Business(
id: json["id"],
alias: json["alias"],
name: json["name"],
imageUrl: json["image_url"],
isClosed: json["is_closed"],
url: json["url"],
reviewCount: json["review_count"],
rating: json["rating"],
);
Map<String, dynamic> toJson() => {
"id": id,
"alias": alias,
"name": name,
"image_url": imageUrl,
"is_closed": isClosed,
"url": url,
"review_count": reviewCount,
"rating": rating,
};
}

How to integrate api using class model in flutter

I'm trying to Integrate the API using model. Let say I have a book screen, so I'm trying to get its API data using model. my model looks like this.
class Book {
final int id;
final String phone;
final String name;
final String relation;
final String updated_at;
final String created_at;
final int userId;
Book(
{required this.id,
required this.name,
required this.phone,
required this.relation,
required this.created_at,
// required this.image,
required this.updated_at,
required this.userId,
});
factory Book.fromJson(Map<String, dynamic> json) => Book(
id: json['user_id'],
name: json['contact_person'],
relation: json['relation'],
phone: json['phone'],
updated_at: json['updated_at'],
created_at: json['created_at'],
userId: json['id']
);
Map<String, dynamic> toJson() => {
'user_id': userId,
'contact_person': phone,
'relation': relation,
'name': name,
'created_at':created_at,
'updated_at':updated_at,
'id':id,
};
}
calling this api like this
Future<List<Book>> getBook() async {
List<Book> _bookList =[];
Map<String, String> headers = {
"Content-type": "application/json",
'Authorization': 'Bearer $token',
};
var url = Uri.parse(ApiPath.getAllEmergenceyContactUrl);
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
Map<String, dynamic> map = json.decode(response.body);
List<dynamic> data = map["user"];
if(data.length>0){
for(int i=0;i<data.length;i++){
if(data[i]!=null){
Map<String,dynamic> map=data[i];
_bookList.add(Book.fromJson(map));
debugPrint('Id-------${map['contact_person']}'); //this print the correct data
}
}
}
print(_bookList);
return _bookList;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
print(_bookList); this give me this output
[Instance of 'Book', Instance of 'Book']
and calling in User Interface like this
List<Book> books = [];
getAllEmergenceyContacts()async{
var books = await services.getBook();
}
i can't able to get the the when using the books in listview builder, please help me out.
my json data look like this
{
"status": 1,
"message": "your emergency contacts",
"user": [
{
"id": 10,
"user_id": 49,
"contact_person": "ABC",
"relation": "DSVKJDSB",
"phone": "sdfsdf",
"image": "emergency/1735686398652391.png",
"created_at": "2022-06-15T07:52:19.000000Z",
"updated_at": "2022-06-15T07:52:19.000000Z"
},
]}
and i want user array data from it.
I optimized your code and fix your problem. You can try it and tell me if have any problem
Model
import 'dart:convert';
Book bookFromJson(String str) => Book.fromJson(json.decode(str));
String bookToJson(Book data) => json.encode(data.toJson());
class Book {
Book({
this.status,
this.message,
this.user,
});
int status;
String message;
List<User> user;
factory Book.fromJson(Map<String, dynamic> json) => Book(
status: json["status"],
message: json["message"],
user: List<User>.from(json["user"].map((x) => User.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"user": List<dynamic>.from(user.map((x) => x.toJson())),
};
}
class User {
User({
this.id,
this.userId,
this.contactPerson,
this.relation,
this.phone,
this.image,
this.createdAt,
this.updatedAt,
});
int id;
int userId;
String contactPerson;
String relation;
String phone;
String image;
DateTime createdAt;
DateTime updatedAt;
factory User.fromJson(Map<String, dynamic> json) => User(
id: json["id"],
userId: json["user_id"],
contactPerson: json["contact_person"],
relation: json["relation"],
phone: json["phone"],
image: json["image"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"user_id": userId,
"contact_person": contactPerson,
"relation": relation,
"phone": phone,
"image": image,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
Call API
Future getBook() async {
Map<String, String> headers = {
"Content-type": "application/json",
'Authorization': 'Bearer $token',
};
var url = Uri.parse(ApiPath.getAllEmergenceyContactUrl);
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
return bookFromJson(response.body).user;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
Calling in ui screen
List<Book> books = [];
getAllEmergenceyContacts()async{
books = await services.getBook();
setState((){});
}
Listview builder
ListView.builder(
itemCount: books.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(books[index].name),
);
},
),
print(_bookList); this gives you this output [Instance of 'Book', Instance of 'Book'] because you try to print every Book class instance
You declare List<Book> _bookList =[]; , where _bookList holds Book Class as a child.
At first, Fetch the books from API
List<Book> books = [];
getAllEmergenceyContacts()async{
var books = await services.getBook();
}
Then, you Should place all the books inside List view builder like the following way
ListView.builder(
itemCount: books.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(books[index].name),
);
},
),

Flutter error || Unhandled Exception: type 'SearchModel' is not a subtype of type 'List<SearchModel>' in type cast

I am making a search in ListView.builder where data is coming in JSON data
I am not getting the error what it wants to say the searchmodel is not a subtype of type List.
or should I go with another approach to work with search in listview.builder
here is my model
import 'dart:convert';
SearchModel searchModelFromJson(String str) =>
SearchModel.fromJson(json.decode(str));
String searchModelToJson(SearchModel data) => json.encode(data.toJson());
class SearchModel {
SearchModel({
required this.data,
required this.meta,
});
final List<Datum> data;
final Meta meta;
factory SearchModel.fromJson(Map<String, dynamic> json) => SearchModel(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
meta: Meta.fromJson(json["meta"]),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"meta": meta.toJson(),
};
}
class Datum {
Datum({
required this.id,
required this.attributes,
});
int? id;
Attributes? attributes;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
attributes: Attributes.fromJson(json["attributes"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"attributes": attributes?.toJson(),
};
}
class Attributes {
Attributes({
required this.name,
required this.mobile,
required this.createdAt,
required this.updatedAt,
required this.shopEmail,
required this.shopUniqueId,
});
String? name;
String? mobile;
String? createdAt;
String? updatedAt;
String? shopEmail;
String? shopUniqueId;
factory Attributes.fromJson(Map<String, dynamic> json) => Attributes(
name: json["name"],
mobile: json["mobile"],
createdAt: json["createdAt"],
updatedAt: json["updatedAt"],
shopEmail: json["shopEmail"],
shopUniqueId: json["shopUniqueId"],
);
Map<String, dynamic> toJson() => {
"name": name,
"mobile": mobile,
"createdAt": createdAt,
"updatedAt": updatedAt,
"shopEmail": shopEmail,
"shopUniqueId": shopUniqueId,
};
}
class Meta {
Meta();
factory Meta.fromJson(Map<String, dynamic> json) => Meta(
);
Map<String, dynamic> toJson() => {
};
}
here is my controller
class FetchSearch {
static Future<SearchModel> getUserList(String? query) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? jwt = prefs.getString('jwt');
var response = await http.get(
Uri.parse(searchUrl),
headers: <String,String> {
'Authorization' : 'Bearer $jwt'
},
);
if (response.statusCode == 200) {
print(response.statusCode);
var stringResponse = response.body;
print(stringResponse);
return SearchModel.fromJson(jsonDecode(stringResponse));
// Map<String,dynamic> search = json.decode(response.body);
// print(search);
// List<dynamic> data = map["data"];
// return search.map((json) => Attributes.fromJson(json)).toList();
}
else {
throw Exception();
}
and here is my variables and init function
int _currentPage = 0, _index = 0;
List<SearchModel> searchItem = [];
String query = '';
Future init() async {
final users = await FetchSearch.getUserList(query);
setState(() => this.searchItem = users as List<SearchModel>);
}