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
Related
I'm trying to make a simple ListView with GetX but it gives me this error when starting the app "Unhandled Exception: NoSuchMethodError: The method 'map' was called on null.", I'm new to flutter and dart, that's why I'm starting with the "easiest" and for work reasons they ask me to add GetX
Home
class HomePage extends GetView<HomeController> {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
// final homeController = Get.put(HomeController());
var title = "HomePage";
return Scaffold(
body: Obx(() {
HomeController controller = Get.find<HomeController>();
return controller.regionList.isEmpty
? const Center(
child: Text('No hay regiones'),
)
: ListView.builder(
itemCount: controller.regionList.length,
itemBuilder: (context, index) => ListTile(
title: Text(
controller.regionList[index].name,
)));
}),
);
}
}
Controller
class HomeController extends GetxController {
//late Regiones model;
var regionList = <Regiones>[].obs;
Future<List<Regiones>> getRegiones() async {
var response = await rootBundle.loadString('assets/response.json');
var results = (jsonDecode(response)['regions'] ?? []) as List;
return results.map((x) => Regiones.fromJson(x)).toList();
//return Regiones.fromJson(jsonDecode(response));
}
//Json['regions'] == null ? Null :
#override
Future<void> onInit() async {
// TODO: implement onInit
super.onInit();
regionList.assignAll(await getRegiones());
}
}
Json
{
"name": "Chile",
"regions": [
{
"name": "Arica y Parinacota",
"romanNumber": "XV",
"number": "15",
"abbreviation": "AP",
"communes": [
{ "name": "Arica", "identifier": "XV-1" },
{ "name": "Camarones", "identifier": "XV-2" },
{ "name": "General Lagos", "identifier": "XV-3" },
{ "name": "Putre", "identifier": "XV-4" }
]
},
{
...
Model
Regiones regionesFromJson(String str) => Regiones.fromJson(json.decode(str));
String regionesToJson(Regiones data) => json.encode(data.toJson());
class Regiones {
Regiones({
required this.name,
required this.regions,
});
String name;
List<Region> regions;
factory Regiones.fromJson(Map<String, dynamic> json) => Regiones(
name: json["name"],
regions:
List<Region>.from(json["regions"].map((x) => Region.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"name": name,
"regions": List<dynamic>.from(regions.map((x) => x.toJson())),
};
}
class Region {
Region({
required this.name,
required this.romanNumber,
required this.number,
required this.abbreviation,
required this.communes,
});
String? name;
String? romanNumber;
String? number;
String? abbreviation;
List<Commune> communes;
factory Region.fromJson(Map<String, dynamic> json) => Region(
name: json["name"],
romanNumber: json["romanNumber"],
number: json["number"],
abbreviation: json["abbreviation"],
communes: List<Commune>.from(
json["communes"].map((x) => Commune.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"name": name,
"romanNumber": romanNumber,
"number": number,
"abbreviation": abbreviation,
"communes": List<dynamic>.from(communes.map((x) => x.toJson())),
};
}
class Commune {
Commune({
required this.name,
required this.identifier,
});
String name;
String identifier;
factory Commune.fromJson(Map<String, dynamic> json) => Commune(
name: json["name"],
identifier: json["identifier"] ?? '',
);
Map<String, dynamic> toJson() => {
"name": name,
"identifier": identifier,
};
}
You call ['regions'] in two place:
1:
var results = (jsonDecode(response)['regions'] ?? []) as List;
2: inside Regiones.fromJson
so in your HomeController instead of this:
return results.map((x) => Regiones.fromJson(x)).toList();
try this:
return results.map((x) => Region.fromJson(x)).toList();
and then make your getRegiones return Future<List> like this:
Future<List<Regione>> getRegiones() async {
...
}
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>);
}
typical json response:
{"data":[{"id":1,"partnerTypeId":1,"active":true,"name":"Covin - AINO UG","shortname":"Covin","firstname":null,"lastname":null,"addressId":1,"phoneId":null,"countryId":"in","email":"support#covin.in","web":"www.covin.in","infos":{},"note":null,"createdAt":"2021-03-06 23:30:30","updatedAt":"2021-03-06 23:30:30","updatedBy":null},{"id":41,"partnerTypeId":100,"active":true,"name":"Tester IND","shortname":"T.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"email#tester","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:02","updatedAt":"2021-03-07 01:25:06","updatedBy":null},{"id":42,"partnerTypeId":100,"active":true,"name":"MIT Charl","shortname":"KITA Ch.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"kisa1#kol","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:42","updatedAt":"2021-03-07 01:25:08","updatedBy":null}]}
Generated podo class:
filename- partnerList.dart
// To parse this JSON data, do
//
// final partnerList = partnerListFromMap(jsonString);
import 'dart:convert';
PartnerList partnerListFromMap(String str) => PartnerList.fromMap(json.decode(str));
String partnerListToMap(PartnerList data) => json.encode(data.toMap());
class PartnerList {
PartnerList({
this.data,
});
List<Datum> data;
factory PartnerList.fromMap(Map<String, dynamic> json) => PartnerList(
data: List<Datum>.from(json["data"].map((x) => Datum.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"data": List<dynamic>.from(data.map((x) => x.toMap())),
};
}
class Datum {
Datum({
this.id,
this.partnerTypeId,
this.active,
this.name,
this.shortname,
this.firstname,
this.lastname,
this.addressId,
this.phoneId,
this.countryId,
this.email,
this.web,
this.infos,
this.note,
this.createdAt,
this.updatedAt,
this.updatedBy,
});
int id;
int partnerTypeId;
bool active;
String name;
String shortname;
dynamic firstname;
dynamic lastname;
int addressId;
dynamic phoneId;
String countryId;
String email;
String web;
Infos infos;
dynamic note;
DateTime createdAt;
DateTime updatedAt;
dynamic updatedBy;
factory Datum.fromMap(Map<String, dynamic> json) => Datum(
id: json["id"],
partnerTypeId: json["partnerTypeId"],
active: json["active"],
name: json["name"],
shortname: json["shortname"],
firstname: json["firstname"],
lastname: json["lastname"],
addressId: json["addressId"] == null ? null : json["addressId"],
phoneId: json["phoneId"],
countryId: json["countryId"],
email: json["email"],
web: json["web"] == null ? null : json["web"],
infos: Infos.fromMap(json["infos"]),
note: json["note"],
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
updatedBy: json["updatedBy"],
);
Map<String, dynamic> toMap() => {
"id": id,
"partnerTypeId": partnerTypeId,
"active": active,
"name": name,
"shortname": shortname,
"firstname": firstname,
"lastname": lastname,
"addressId": addressId == null ? null : addressId,
"phoneId": phoneId,
"countryId": countryId,
"email": email,
"web": web == null ? null : web,
"infos": infos.toMap(),
"note": note,
"createdAt": createdAt.toIso8601String(),
"updatedAt": updatedAt.toIso8601String(),
"updatedBy": updatedBy,
};
}
class Infos {
Infos();
factory Infos.fromMap(Map<String, dynamic> json) => Infos(
);
Map<String, dynamic> toMap() => {
};
}
related fetch class: file name - partner.api.dart
import 'partnerList.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
Future<List<PartnerList>> fetchPartner() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final userid = prefs.getString('user_id');
final token = prefs.getString('token');
Map<String, String> requestHeaders = {
'Accept': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $token',
};
final response = await http.get("https://api.covin.in/partners/",
headers: requestHeaders);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response.body);
return partnerListFromMap(response.body);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load PartnerList');
}
}
Now the first error I am getting:
A value of type 'PartnerList' can't be returned from the function 'fetchPartner' because it has a return type of 'Future<List<PartnerList>>'.dartreturn_of_invalid_type
how I can fix this?
update: I have modified the function partnerListfromMap like below:
List<PartnerList> partnerListFromMap(String str) => List<PartnerList>.from(json.decode(str));
String partnerListToMap(PartnerList data) => json.encode(data.toMap());
but I am getting another error now:
Exception has occurred. _TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>')
You can copy paste run full code below
Your json string is PartnerList not List<PartnerList>
You can use Future<PartnerList> and use return Future.value
code snippet
Future<PartnerList> fetchPartner() async {
...
return Future.value(partnerListFromMap(response.body));
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
PartnerList partnerListFromMap(String str) =>
PartnerList.fromMap(json.decode(str));
String partnerListToMap(PartnerList data) => json.encode(data.toMap());
class PartnerList {
PartnerList({
this.data,
});
List<Datum> data;
factory PartnerList.fromMap(Map<String, dynamic> json) => PartnerList(
data: List<Datum>.from(json["data"].map((x) => Datum.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"data": List<dynamic>.from(data.map((x) => x.toMap())),
};
}
class Datum {
Datum({
this.id,
this.partnerTypeId,
this.active,
this.name,
this.shortname,
this.firstname,
this.lastname,
this.addressId,
this.phoneId,
this.countryId,
this.email,
this.web,
this.infos,
this.note,
this.createdAt,
this.updatedAt,
this.updatedBy,
});
int id;
int partnerTypeId;
bool active;
String name;
String shortname;
dynamic firstname;
dynamic lastname;
int addressId;
dynamic phoneId;
String countryId;
String email;
String web;
Infos infos;
dynamic note;
DateTime createdAt;
DateTime updatedAt;
dynamic updatedBy;
factory Datum.fromMap(Map<String, dynamic> json) => Datum(
id: json["id"],
partnerTypeId: json["partnerTypeId"],
active: json["active"],
name: json["name"],
shortname: json["shortname"],
firstname: json["firstname"],
lastname: json["lastname"],
addressId: json["addressId"] == null ? null : json["addressId"],
phoneId: json["phoneId"],
countryId: json["countryId"],
email: json["email"],
web: json["web"] == null ? null : json["web"],
infos: Infos.fromMap(json["infos"]),
note: json["note"],
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
updatedBy: json["updatedBy"],
);
Map<String, dynamic> toMap() => {
"id": id,
"partnerTypeId": partnerTypeId,
"active": active,
"name": name,
"shortname": shortname,
"firstname": firstname,
"lastname": lastname,
"addressId": addressId == null ? null : addressId,
"phoneId": phoneId,
"countryId": countryId,
"email": email,
"web": web == null ? null : web,
"infos": infos.toMap(),
"note": note,
"createdAt": createdAt.toIso8601String(),
"updatedAt": updatedAt.toIso8601String(),
"updatedBy": updatedBy,
};
}
class Infos {
Infos();
factory Infos.fromMap(Map<String, dynamic> json) => Infos();
Map<String, dynamic> toMap() => {};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<PartnerList> _future;
Future<PartnerList> fetchPartner() async {
String jsonString = '''
{"data":[{"id":1,"partnerTypeId":1,"active":true,"name":"Covin - AINO UG","shortname":"Covin","firstname":null,"lastname":null,"addressId":1,"phoneId":null,"countryId":"in","email":"support#covin.in","web":"www.covin.in","infos":{},"note":null,"createdAt":"2021-03-06 23:30:30","updatedAt":"2021-03-06 23:30:30","updatedBy":null},{"id":41,"partnerTypeId":100,"active":true,"name":"Tester IND","shortname":"T.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"email#tester","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:02","updatedAt":"2021-03-07 01:25:06","updatedBy":null},{"id":42,"partnerTypeId":100,"active":true,"name":"MIT Charl","shortname":"KITA Ch.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"kisa1#kol","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:42","updatedAt":"2021-03-07 01:25:08","updatedBy":null}]}
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response.body);
return Future.value(partnerListFromMap(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load PartnerList');
}
}
#override
void initState() {
_future = fetchPartner();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<PartnerList> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data.data[index].id
.toString()),
Spacer(),
Text(
snapshot.data.data[index].name,
),
],
),
));
});
}
}
}));
}
}
Try this:
// this is correct. I think you generated this using app.quicktype.io ? Then it's correct.
PartnerList partnerListFromMap(String str) => PartnerList.fromMap(json.decode(str));
// you want the list of Datum.
Future<List<Datum>> fetchPartner() async {
// other codes here ...
return partnerListFromMap(response.body).data;
// other codes here ...
}
Here is my code
final List<Dummy> loadedItems = [];
//dummy data
final requiredData = {"vendor":"Avatar" ,"grocery_category":[{"category_name":"Fruits", "sub_categories":[{"category_name":"Apple", "items":[{"item_name":"redApple", "item_price":"250"}]}]}]};
loadedItems.add(Dummy(
title: requiredData['vendor'],
subtitle: (requiredData['grocery_category'] as List<dynamic>).map((item) {
Dummy2(item['category_name']);
}).toList()
));
Models
class Dummy {
final String title;
final List<Dummy2> subtitle;
Dummy({this.title, this.subtitle});
}
class Dummy2 {
final String subTitle;
Dummy2(this.subTitle);
}
If i printed like this,
print(loadedItems[0].title);
Output is,
Avatar
By the same way, if i printed like this,
print(loadedItems[0].subtitle);
Output is,
null
I dont know what's the mistake I'm doing... I tried so far but couldn't find why its like this. Please give me a solution. Thanks in Advance!
json you provided :
{
"vendor": "Avatar",
"grocery_category": [{
"category_name": "Fruits",
"sub_categories": [{
"category_name": "Apple",
"items": [{
"item_name": "redApple",
"item_price": "250"
}]
}]
}]
}
Check out this model for your json:
// To parse this JSON data, do
//
// final groceryModel = groceryModelFromJson(jsonString);
import 'dart:convert';
GroceryModel groceryModelFromJson(String str) => GroceryModel.fromJson(json.decode(str));
String groceryModelToJson(GroceryModel data) => json.encode(data.toJson());
class GroceryModel {
GroceryModel({
this.vendor,
this.groceryCategory,
});
String vendor;
List<GroceryCategory> groceryCategory;
factory GroceryModel.fromJson(Map<String, dynamic> json) => GroceryModel(
vendor: json["vendor"],
groceryCategory: List<GroceryCategory>.from(json["grocery_category"].map((x) => GroceryCategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"vendor": vendor,
"grocery_category": List<dynamic>.from(groceryCategory.map((x) => x.toJson())),
};
}
class GroceryCategory {
GroceryCategory({
this.categoryName,
this.subCategories,
});
String categoryName;
List<SubCategory> subCategories;
factory GroceryCategory.fromJson(Map<String, dynamic> json) => GroceryCategory(
categoryName: json["category_name"],
subCategories: List<SubCategory>.from(json["sub_categories"].map((x) => SubCategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category_name": categoryName,
"sub_categories": List<dynamic>.from(subCategories.map((x) => x.toJson())),
};
}
class SubCategory {
SubCategory({
this.categoryName,
this.items,
});
String categoryName;
List<Item> items;
factory SubCategory.fromJson(Map<String, dynamic> json) => SubCategory(
categoryName: json["category_name"],
items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category_name": categoryName,
"items": List<dynamic>.from(items.map((x) => x.toJson())),
};
}
class Item {
Item({
this.itemName,
this.itemPrice,
});
String itemName;
String itemPrice;
factory Item.fromJson(Map<String, dynamic> json) => Item(
itemName: json["item_name"],
itemPrice: json["item_price"],
);
Map<String, dynamic> toJson() => {
"item_name": itemName,
"item_price": itemPrice,
};
}
main page
import 'package:flutter/material.dart';
import 'package:json_parsing_example/models.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: Login());
}
}
class Login extends StatefulWidget {
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
List<Grocery> items = List();
#override
void initState() {
super.initState();
getData();
}
getData() async {
String data =
await DefaultAssetBundle.of(context).loadString("json/parse.json");
final grocery = groceryFromJson(data);
items.add(grocery);
print(items[0].vendor);
print(items[0].groceryCategory[0].categoryName);
print(items[0].groceryCategory[0].subCategories[0].categoryName);
print(items[0].groceryCategory[0].subCategories[0].items[0].itemName);
print(items[0].groceryCategory[0].subCategories[0].items[0].itemPrice);
}
#override
Widget build(BuildContext context) {
return Scaffold(body: Text('Example'));
}
}
Let me know if it works. you can access the items inside.
This seems to work for me
void main() {
final List<Dummy> loadedItems = [];
//dummy data
final requiredData = {"vendor":"Avatar" ,"grocery_category":[{"category_name":"Fruits", "sub_categories":[{"category_name":"Apple", "items":[{"item_name":"redApple", "item_price":"250"}]}]}]};
loadedItems.add(Dummy(
title: requiredData['vendor'],
subtitle: (requiredData['grocery_category'] as List).map((dummy2) => Dummy2(dummy2['category_name'])).toList()
));
print(loadedItems[0].title);
print(loadedItems[0].subtitle);
}
class Dummy {
final String title;
final List<Dummy2> subtitle;
Dummy({this.title, this.subtitle});
}
class Dummy2 {
final String subTitle;
Dummy2(this.subTitle);
#override
String toString(){
return 'subTitle: $subTitle';
}
}
you can paste it in to dartpad to play around with it and see how it works
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'];
}
}