Occurs exception when I get the chapter list.
So how can I solve this problem?
Please help.
Here is my API response.
{
"success": 1,
"chapter": [
{
"chapter_id": "609cb13f497e3",
"chapter_name": "test",
"subject_id": "5e32874c714fa",
"medium_id": "5d15938aa1344",
"standard_id": "5d1594e283e1a",
"material": null,
"textbook": null,
"test_paper": null,
"test_paper_solution": null,
"subject_memory_map": null,
"active": "1"
}
]
}
The model class which I created in chapter_model.dart file.
// To parse this JSON data, do
//
// final chapterBySubjectModel = chapterBySubjectModelFromJson(jsonString);
import 'dart:convert';
ChapterBySubjectModel chapterBySubjectModelFromJson(String str) => ChapterBySubjectModel.fromJson(json.decode(str));
String chapterBySubjectModelToJson(ChapterBySubjectModel data) => json.encode(data.toJson());
class ChapterBySubjectModel {
ChapterBySubjectModel({
required this.success,
required this.chapter,
});
int success;
List<Chapter> chapter;
factory ChapterBySubjectModel.fromJson(Map<String, dynamic> json) => ChapterBySubjectModel(
success: json["success"],
chapter: List<Chapter>.from(json["chapter"].map((x) => Chapter.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success,
"chapter": List<dynamic>.from(chapter.map((x) => x.toJson())),
};
}
class Chapter {
Chapter({
required this.chapterId,
required this.chapterName,
required this.subjectId,
required this.mediumId,
required this.standardId,
this.material,
this.textbook,
this.testPaper,
this.testPaperSolution,
this.subjectMemoryMap,
required this.active,
});
String chapterId;
String chapterName;
String subjectId;
String mediumId;
String standardId;
dynamic material;
dynamic textbook;
dynamic testPaper;
dynamic testPaperSolution;
dynamic subjectMemoryMap;
String active;
factory Chapter.fromJson(Map<String, dynamic> json) => Chapter(
chapterId: json["chapter_id"],
chapterName: json["chapter_name"],
subjectId: json["subject_id"],
mediumId: json["medium_id"],
standardId: json["standard_id"],
material: json["material"],
textbook: json["textbook"],
testPaper: json["test_paper"],
testPaperSolution: json["test_paper_solution"],
subjectMemoryMap: json["subject_memory_map"],
active: json["active"],
);
Map<String, dynamic> toJson() => {
"chapter_id": chapterId,
"chapter_name": chapterName,
"subject_id": subjectId,
"medium_id": mediumId,
"standard_id": standardId,
"material": material,
"textbook": textbook,
"test_paper": testPaper,
"test_paper_solution": testPaperSolution,
"subject_memory_map": subjectMemoryMap,
"active": active,
};
}
Method which i Created in api_manager.dart file.
Future<List<Chapter>> getChapterBySubject() async {
final chapterUrl =
'$baseUrl/subject/get_by_user_plan?user_id=609cab2cd5b6c&order_id=1620889722609cd07a601af469889697609cab2cd5b6c&standard_id=5d1594e283e1a&medium_id=5d15938aa1344';
final response = await http.get(Uri.parse(chapterUrl));
if (response.statusCode == 200) {
final chapterData = chapterBySubjectModelFromJson(response.body);
final List<Chapter> chapters = chapterData.chapter;
print(chapters);
return chapters;
} else {
return <Chapter>[];
}
}
And view as below in chapter_widget.dart file.
class _ChapterWidgetState extends State<ChapterWidget> {
late bool _loading;
var _chapters = <Chapter>[];
#override
void initState() {
super.initState();
_loading = true;
ApiManager().getChapterBySubject().then((chapters) {
setState(() {
_chapters = chapters;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: null == _chapters ? 0 : _chapters.length,
//itemCount: _chapters.length,
itemBuilder: (context, index) {
Chapter chapter = _chapters[index];
return Container(
padding: EdgeInsets.all(8),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: InkWell(
//child: Image.asset("assets/logos/listbackground.png"),
child: Text(chapter.chapterName),
),
),
),
);
});
}
}
It throws an Exception in Model Class in below line.
List<Chapter>.from(json["chapter"].map((x) => Chapter.fromJson(x))),
You set chapter as required but it seems API says it can be null. So, you should convert your parameters from required to nullable like this:
import 'dart:convert';
ChapterBySubjectModel chapterBySubjectModelFromJson(String str) => ChapterBySubjectModel.fromJson(json.decode(str));
String chapterBySubjectModelToJson(ChapterBySubjectModel data) => json.encode(data.toJson());
class ChapterBySubjectModel {
ChapterBySubjectModel({
this.success,
this.chapter,
});
int success;
List<Chapter> chapter;
factory ChapterBySubjectModel.fromJson(Map<String, dynamic> json) => ChapterBySubjectModel(
success: json["success"] == null ? null : json["success"],
chapter: json["chapter"] == null ? null : List<Chapter>.from(json["chapter"].map((x) => Chapter.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success == null ? null : success,
"chapter": chapter == null ? null : List<Chapter>.from(chapter.map((x) => x)),
};
}
Related
I'm trying to view data that comes from API with GetX
but there is something wrong I tried to fix it but I can't
What's the problem guys please
this is my controller:
class ProductController extends GetxController {
var productsList = <Product>[].obs;
var isLoading = true.obs;
#override
void onInit() {
fetchProducts();
super.onInit();
}
void fetchProducts() async {
try {
var product = await RemoteServices.fetchData();
if (product != null) {
productsList.value = product;
isLoading.value = false;
}
} catch (e) {
print(e);
}
}
}
and this is Remote Service:
class RemoteServices {
static var client = http.Client();
static Future<List<Product>> fetchData() async {
final uri = Uri.parse(
"https://makeup-api.herokuapp.com/api/v1/products.json?product_type=blush");
final response = await client.get(uri);
if (response.statusCode == 200) {
var jsonData = json.decode(response.body);
final productsListJson =
(jsonData[''] as List).map((e) => Product.fromJson(e)).toList();
//jsonData['data']^^^
print("its WORK SUCCESSFULLY");
return productsListJson;
} else {
throw Exception('Something Wrong :(');
}
}
}
and this is View Page :
class HomePage extends StatelessWidget {
final productController = Get.put(ProductController());
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.purple,
body: Obx(() => productController.isLoading.value
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemCount: productController.productsList.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Column(
children: [
Image.network(productController
.productsList[index].imageLink
.toString()),
Text(productController.productsList[index].name
.toString()),
Text(productController.productsList[index].price
.toString()),
],
),
);
},
)),
);
}
}
when I run the app The CircularProgressIndicator() still running and the run page tell me :
Syncing files to device Android SDK built for x86...
Restarted application in 4,096ms.
[GETX] Instance "ProductController" has been created
[GETX] Instance "ProductController" has been initialized
I/flutter (28829): type 'String' is not a subtype of type 'int' of 'index'
I checked your code and fixed the issues. Here the code...
RemoteService
class RemoteServices {
static var client = http.Client();
static Future<List<Product>> fetchData() async {
final uri = Uri.parse("https://makeup-api.herokuapp.com/api/v1/products.json?product_type=blush");
final response = await client.get(uri);
if (response.statusCode == 200) {
var jsonData = json.decode(response.body);
final productsListJson = List<Product>.from(jsonData.map((x) => Product.fromJson(x)));
print("its WORK SUCCESSFULLY");
return productsListJson;
} else {
throw Exception('Something Wrong :(');
}
}
}
Product Model class
List<Product> productFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Product {
Product({
this.id,
this.brand,
this.name,
this.price,
this.priceSign,
this.currency,
this.imageLink,
this.productLink,
this.websiteLink,
this.description,
this.rating,
this.category,
this.productType,
this.tagList,
this.createdAt,
this.updatedAt,
this.productApiUrl,
this.apiFeaturedImage,
this.productColors,
});
int? id;
String? brand;
String? name;
String? price;
String? priceSign;
String? currency;
String? imageLink;
String? productLink;
String? websiteLink;
String? description;
double? rating;
String? category;
String? productType;
List<String>? tagList;
DateTime? createdAt;
DateTime? updatedAt;
String? productApiUrl;
String? apiFeaturedImage;
List<ProductColor>? productColors;
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"],
brand: json["brand"] == null ? null : json["brand"],
name: json["name"],
price: json["price"] == null ? null : json["price"],
priceSign: json["price_sign"] == null ? null : json["price_sign"],
currency: json["currency"] == null ? null : json["currency"],
imageLink: json["image_link"],
productLink: json["product_link"],
websiteLink: json["website_link"],
description: json["description"] == null ? null : json["description"],
rating: json["rating"] == null ? null : json["rating"].toDouble(),
category: json["category"] == null ? null : json["category"],
productType: json["product_type"],
tagList: List<String>.from(json["tag_list"].map((x) => x)),
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
productApiUrl: json["product_api_url"],
apiFeaturedImage: json["api_featured_image"],
productColors: List<ProductColor>.from(json["product_colors"].map((x) => ProductColor.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"brand": brand == null ? null : brand,
"name": name,
"price": price == null ? null : price,
"price_sign": priceSign == null ? null : priceSign,
"currency": currency == null ? null : currency,
"image_link": imageLink,
"product_link": productLink,
"website_link": websiteLink,
"description": description == null ? null : description,
"rating": rating == null ? null : rating,
"category": category == null ? null : category,
"product_type": productType,
"tag_list": List<dynamic>.from(tagList!.map((x) => x)),
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
"product_api_url": productApiUrl,
"api_featured_image": apiFeaturedImage,
"product_colors": List<dynamic>.from(productColors!.map((x) => x.toJson())),
};
}
class ProductColor {
ProductColor({
this.hexValue,
this.colourName,
});
String? hexValue;
String? colourName;
factory ProductColor.fromJson(Map<String, dynamic> json) => ProductColor(
hexValue: json["hex_value"],
colourName: json["colour_name"] == null ? null : json["colour_name"],
);
Map<String, dynamic> toJson() => {
"hex_value": hexValue,
"colour_name": colourName == null ? null : colourName,
};
}
Main reson of the error should be the type convertion, try this or just care to this point
final productsListJson = (jsonData as List).map((e) => Product.fromJson(e)).toList();
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 want to display list of videos with thumbnails from api.
Here is the api response as below.
{
"success": 1,
"video": [
{
"video_id": "609cb28a0760c",
"url": "https://www.youtube.com/watch?v=EvvHNtlz20Q&list=RDEvvHNtlz20Q&start_radio=1",
"search_by": "",
"topic_id": "609cb1dce30aa",
"chapter_id": "609cb13f497e3",
"subject_id": "5e32874c714fa",
"medium_id": "5d15938aa1344",
"standard_id": "5d1594e283e1a",
"topic_name": "test topic",
"active": "1"
}
]
}
From above response i created Model Class as below in videomodel.dart file.
// To parse this JSON data, do
//
// final videoModel = videoModelFromJson(jsonString);
import 'dart:convert';
VideoModel videoModelFromJson(String str) =>
VideoModel.fromJson(json.decode(str));
String videoModelToJson(VideoModel data) => json.encode(data.toJson());
class VideoModel {
VideoModel({
required this.success,
required this.video,
});
int success;
List<Video> video;
factory VideoModel.fromJson(Map<String, dynamic> json) => VideoModel(
success: json["success"],
video: List<Video>.from(json["video"].map((x) => Video.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success,
"video": List<dynamic>.from(video.map((x) => x.toJson())),
};
}
class Video {
Video({
required this.videoId,
required this.url,
required this.searchBy,
required this.topicId,
required this.chapterId,
required this.subjectId,
required this.mediumId,
required this.standardId,
required this.topicName,
required this.active,
});
String videoId;
String url;
String searchBy;
String topicId;
String chapterId;
String subjectId;
String mediumId;
String standardId;
String topicName;
String active;
factory Video.fromJson(Map<String, dynamic> json) => Video(
videoId: json["video_id"],
url: json["url"],
searchBy: json["search_by"],
topicId: json["topic_id"],
chapterId: json["chapter_id"],
subjectId: json["subject_id"],
mediumId: json["medium_id"],
standardId: json["standard_id"],
topicName: json["topic_name"],
active: json["active"],
);
Map<String, dynamic> toJson() => {
"video_id": videoId,
"url": url,
"search_by": searchBy,
"topic_id": topicId,
"chapter_id": chapterId,
"subject_id": subjectId,
"medium_id": mediumId,
"standard_id": standardId,
"topic_name": topicName,
"active": active,
};
}
Here is the Function i created in apimanager.dart file.
Future<List<Video>> getVideo() async {
final videoUrl =
"$baseUrl/videos/get_by_standard_medium_subject_chapter_id?subject_id=5e32874c714fa&medium_id=5d15938aa1344&standard_id=5d1594e283e1a&chapter_id=609cb13f497e3";
final response = await http.get(Uri.parse(videoUrl));
if (response.statusCode == 200) {
final videoData = videoModelFromJson(response.body);
final List<Video> videos = videoData.video;
return videos;
} else {
return <Video>[];
}
}
And last is view code as below in video_widget.dart file.
class _VideoWidgetState extends State<VideoWidget> {
var _videos = <Video>[];
late bool _loading;
#override
void initState() {
super.initState();
_loading = true;
ApiManager().getVideo().then((videos) {
setState(() {
_videos = videos;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: null == _videos ? 0 : _videos.length,
//itemCount: _subjects.length,
itemBuilder: (context, index) {
Video video = _videos[index];
});
}
}
So how can i display the list of videos with the thumbnails?
Simply using YoutubeVideoController I solved the problem.
ListView.builder(
itemCount: null == _videos ? 0 : _videos.length,
itemBuilder: (context, index) {
Video video = _videos[index];
var url = video.url;
YoutubePlayerController _controller = YoutubePlayerController(
initialVideoId: YoutubePlayer.getThumbnail(videoId: url),
flags: YoutubePlayerFlags(
autoPlay: false,
mute: false,
disableDragSeek: false,
loop: false,
isLive: false,
forceHD: false,
),
);
return YoutubePlayer(
controller: _controller,
);
},
),
I want to get data of each element inside "invoices" to show but I don't know why it has a problem when I try to call "DataAllInvoice" class.
Please help me fix this problem.
Data API
{
"invoices": [
{
"id": 3,
"customer_id": 6,
"customer_name": "Nguyễn Công Phượng",
"creater_id": 2,
"creater_name": "Lê Minh Tuấn",
"create_time": "2021-05-16T10:05:43",
"total": 411107.0,
"description": "ABC",
"manager_confirm_id": 0,
"manager_confirm_name": null,
"manager_confirm_date": null,
"customer_confirm_date": null,
"status_id": 4
},
{
"id": 2,
"customer_id": 3,
"customer_name": "Nguyễn Văn A",
"creater_id": 2,
"creater_name": "Lê Minh Tuấn",
"create_time": "2021-05-14T10:05:43",
"total": 411107.0,
"description": "ABC",
"manager_confirm_id": 0,
"manager_confirm_name": null,
"manager_confirm_date": null,
"customer_confirm_date": null,
"status_id": 1
},
{
"id": 1,
"customer_id": 3,
"customer_name": "Nguyễn Văn A",
"creater_id": 2,
"creater_name": "Lê Minh Tuấn",
"create_time": "2021-05-14T09:28:43",
"total": 222220.0,
"description": "ABC",
"manager_confirm_id": 0,
"manager_confirm_name": null,
"manager_confirm_date": null,
"customer_confirm_date": null,
"status_id": 5
}
],
"total": 3
}
Class to call API
class GetInvoice{
static int statusInvoice;
createInvoice() async {
final response = await http.get(
Uri.parse("http://3.137.137.156:5000/api/rtm/v1/invoice/get-invoice?customer_id=0&pageNum=10&pageNo=1&from=%20&to=2021-05-14%2012%3A00%3A00"),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIwMTIzNDU2Nzg4IiwiaWF0IjoxNjIyNjI0MjAyLCJleHAiOjE2MjMyMjkwMDJ9.zkf23Da4-TR5sVZgtXjXvczERhaNT1teeX5k-mQaKK6lbE0l28j5TwY5ZqPL252AEAaT8W1jyEUijG-rQiSu5Q',
},
);
print("Status getApi Invoice:${response.statusCode}");
statusInvoice = response.statusCode;
if (response.statusCode == 200) {
Invoice invoice = Invoice.fromJson(jsonDecode(response.body));
List<DataAllInvoice> _invoice;
for(int i=0;i < invoice.invoices.length;i++){
if(invoice.invoices[i]!=null){
Map<String,dynamic> map=invoice.invoices[i];
_invoice.add(DataAllInvoice.fromJson(map)); ****Not working here****
}
}
return _invoice;
} else {
// throw an exception.
throw Exception('Failed to load data');
}
}
Class have a problem when I try to call - DataAllInvoice class
class DataAllInvoice {
final int id, customer_id, creater_id, total, manager_confirm_id, status_id;
final String customer_name, manager_confirm_name;
final String creater_name, description;
final DateTime create_time, manager_confirm_date, customer_confirm_date;
DataAllInvoice(
{this.id,
this.customer_id,
this.creater_id,
this.total,
this.manager_confirm_id,
this.status_id,
this.customer_name,
this.manager_confirm_name,
this.creater_name,
this.description,
this.create_time,
this.manager_confirm_date,
this.customer_confirm_date
});
factory DataAllInvoice.fromJson(Map<String, dynamic> json) {
return DataAllInvoice(
id: json[" id"],
customer_id: json[" customer_id"],
creater_id: json[" creater_id"],
total: json[" total"],
manager_confirm_id: json[" manager_confirm_id"],
status_id: json[" status_id"],
customer_name: json[" customer_name"],
manager_confirm_name: json[" manager_confirm_name"],
creater_name: json[" creater_name"],
description: json[" description"],
create_time: DateTime.parse(json[" create_time"]),
manager_confirm_date: DateTime.parse(json[" manager_confirm_date"]),
customer_confirm_date: DateTime.parse(json[" customer_confirm_date"]),
);
}
}
Invoice Class
class Invoice {
final List invoices;
final int total;
Invoice({this.invoices, this.total});
factory Invoice.fromJson(Map<String, dynamic> json) {
return Invoice(
invoices: json["invoices"],
total: json["total"],
);
}
}
Try That :
So here Fetch Api Class
Sometime you gotta need to use Uri.parse() to put the URL inside it.
and you have to check the statusCode is equal 200 Otherwise there is problem.
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'DataCardFromApi.dart';
class FetchApi {
static Future<List<Articles>> fetchStory() async {
var url = Uri.parse("https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=c5609b49c9274e89bacde5dcab5c52a2");
http.Response response = await http.get(url);
if (response.statusCode == 200) {
Map<String, dynamic> resMap = jsonDecode(response.body);
List listNews = resMap['articles'];
return listNews.map((e) => Articles.fromJson(e)).toList();
}
return null;
}
}
So the second Step :
you have to copy All Code Of Json and convert to Dart Code via This Link
You will get a code like this :
class NewsModel {
String status;
int totalResults;
List<Articles> articles;
NewsModel({this.status, this.totalResults, this.articles});
NewsModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
totalResults = json['totalResults'];
if (json['articles'] != null) {
articles = new List<Articles>();
json['articles'].forEach((v) {
articles.add(new Articles.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
data['totalResults'] = this.totalResults;
if (this.articles != null) {
data['articles'] = this.articles.map((v) => v.toJson()).toList();
}
return data;
}
}
class Articles {
Source source;
String author;
String title;
String description;
String url;
String urlToImage;
String publishedAt;
String content;
Articles(
{this.source,
this.author,
this.title,
this.description,
this.url,
this.urlToImage,
this.publishedAt,
this.content});
Articles.fromJson(Map<String, dynamic> json) {
source =
json['source'] != null ? new Source.fromJson(json['source']) : null;
author = json['author'];
title = json['title'];
description = json['description'];
url = json['url'];
urlToImage = json['urlToImage'];
publishedAt = json['publishedAt'];
content = json['content'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.source != null) {
data['source'] = this.source.toJson();
}
data['author'] = this.author;
data['title'] = this.title;
data['description'] = this.description;
data['url'] = this.url;
data['urlToImage'] = this.urlToImage;
data['publishedAt'] = this.publishedAt;
data['content'] = this.content;
return data;
}
}
class Source {
String id;
String name;
Source({this.id, this.name});
Source.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
The Third step :
you have to create a Function loadData like this and after that you will put it inside initState to get data
watch this code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/StoryModel.dart';
import 'Fetch_Api.dart';
import 'New_Page.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Articles> listModel;
#override
void initState() {
// TODO: implement initState
super.initState();
loadData() ;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(""),
actions: [
Padding(padding: EdgeInsets.only(right: 20.0),child: Icon(Icons.search_rounded))],
backgroundColor: Colors.indigo,
),
body: SafeArea(child: listModel != null ? ListView.builder(
shrinkWrap: true,
itemCount: listModel.length,
itemBuilder: (_ , index){
Articles model = listModel[index] ;
if(model.urlToImage != null)
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
InkWell(
onTap:()=> onPressCallback(model),
child: ClipRRect(
borderRadius: BorderRadius.circular(30.0),
child: Image.network(model.urlToImage,)),),
Text(model.title,style: TextStyle(fontSize: 27.0,fontWeight:FontWeight.bold),),
SizedBox(height: 20,),],
),
) ;
return SizedBox();
}) : Center(child: Text('Loading data ... ')),)
);
}
void loadData() async{
listModel = await FetchApi.fetchStory() ;
setState(() {});
}
void onPressCallback(Articles model) {
Navigator.push(context, MaterialPageRoute(builder: (_) => NewPage(model: model)));
}
}
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 ...
}