I am trying to get data from my model but I am not getting the data in text widget.After receiving data from JSON I am using model to save data I am able to print data after API call in function but not when I tried to get data from model inside widget.I am using provider
but receiving null value from model I am not getting exactly how to achieve this task following is my JSON object
{
"statusCode": 200,
"success": true,
"messages": [],
"data": [
{
"id": 36,
"title": "Muhurtam",
"filename": "Muhurtam.jpg",
"mimetype": "image/jpeg",
"directcalling": 1,
"parentid": null,
"subcat": [
{
"id": 50,
"title": "abc",
"filename": "abc.png",
"mimetype": "image/png",
"directcalling": 0,
"parentid": 36,
"subcat": []
}
]
I had created model class for the above json below is my model
Model
import 'package:flutter/material.dart';
class Categories with ChangeNotifier {
Categories({
this.statusCode,
this.success,
this.messages,
this.data,
});
late final int? statusCode;
late final bool? success;
late final List<dynamic>? messages;
late final List<Data>? data;
Categories.fromJson(Map<String, dynamic> json) {
statusCode = json['statusCode'];
success = json['success'];
messages = List.castFrom<dynamic, dynamic>(json['messages']);
data = List.from(json['data']).map((e) => Data.fromJson(e)).toList();
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
_data['statusCode'] = statusCode;
_data['success'] = success;
_data['messages'] = messages;
_data['data'] = data!.map((e) => e.toJson()).toList();
return _data;
}
List get items {
// if (_showFavoritesOnly) {
// return _items.where((prodItem) => prodItem.isFavorite).toList();
// }
return [...data!];
}
}
class Data extends ChangeNotifier {
Data({
this.id,
this.title,
this.filename,
this.mimetype,
this.directcalling,
this.parentid,
this.subcat,
});
late final int? id;
late final String? title;
late final String? filename;
late final String? mimetype;
late final int? directcalling;
late final Null parentid;
late final List<Subcat>? subcat;
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
filename = json['filename'];
mimetype = json['mimetype'];
directcalling = json['directcalling'];
parentid = null;
subcat = List.from(json['subcat']).map((e) => Subcat.fromJson(e)).toList();
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
// _data['id'] = id;
_data['title'] = title;
_data['filename'] = filename;
// _data['mimetype'] = mimetype;
_data['directcalling'] = directcalling;
// _data['parentid'] = parentid;
// _data['subcat'] = subcat.map((e) => e.toJson()).toList();
return _data;
}
}
class Subcat {
Subcat({
required this.id,
required this.title,
required this.filename,
required this.mimetype,
required this.directcalling,
required this.parentid,
required this.subcat,
});
late final int id;
late final String title;
late final String filename;
late final String mimetype;
late final int directcalling;
late final int parentid;
late final List<dynamic> subcat;
Subcat.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
filename = json['filename'];
mimetype = json['mimetype'];
directcalling = json['directcalling'];
parentid = json['parentid'];
subcat = List.castFrom<dynamic, dynamic>(json['subcat']);
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
//_data['id'] = id;
_data['title'] = title;
_data['filename'] = filename;
//_data['mimetype'] = mimetype;
_data['directcalling'] = directcalling;
//_data['parentid'] = parentid;
//_data['subcat'] = subcat;
return _data;
}
}
following is my widget where I want to check data inside my model.i am not getting exactly how to call data which is inside model
Widget build(BuildContext context) {
var image = Provider.of<FlutterFunctions>(context, listen: false);
var cat = Provider.of<Category>(context, listen: false).categories;
return Scaffold(
appBar: AppBar(),
drawer: const AppDrawer(),
body: Text("${cat?.data == null ? "there is no data" : cat!.statusCode}")
Api Conversion
class Category with ChangeNotifier {
Categories? categories;
Future<void> getCatogories(BuildContext cont) async {
final url = PurohitApi().baseUrl PurohitApi().getcategory;
try {
final client = RetryClient(
http.Client(),
retries: 4,
when: (response) {
return response.statusCode == 401 ? true : false;
},
onRetry: (req, res, retryCount) async {
//print('retry started $token');
if (retryCount == 0 && res?.statusCode == 401) {
var accessToken = await Provider.of<Auth>(cont, listen: false)
.restoreAccessToken();
// Only this block can run (once) until done
req.headers['Authorization'] = accessToken;
}
},
);
var response = await client.get(
Uri.parse(url),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
);
Map<String, dynamic> categoryTypes = json.decode(response.body);
categories = Categories.fromJson(categoryTypes);
notifyListeners();
} catch (e) {
print(e);
}
}
}
CodePudding user response:
You are using Provider
the wrong way. Your models such as Categories
,Data
etc. should not extend ChangeNotifier. You have to make Provider
class which uses ChangeNotifier
which will have your model data and provide it somewhere to use it with Provider.of<ProviderName>(context, listen: false)
. Something like this:
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (ctx) => CategoriesProvider(),
child: MaterialApp(
home: Sample(),
),
);
}
}
class CategoriesProvider with ChangeNotifier {
Categories? categories;
Future<void> getCatogories() async {
Map<String, dynamic> categoryTypes = {
"statusCode": 200,
"success": true,
"messages": [],
"data": [
{
"id": 36,
"title": "Muhurtam",
"filename": "Muhurtam.jpg",
"mimetype": "image/jpeg",
"directcalling": 1,
"parentid": null,
"subcat": [
{
"id": 50,
"title": "abc",
"filename": "abc.png",
"mimetype": "image/png",
"directcalling": 0,
"parentid": 36,
"subcat": []
}
]
}
]
};
categories = Categories.fromJson(categoryTypes);
notifyListeners();
}
}
class Sample extends StatefulWidget {
const Sample({Key? key}) : super(key: key);
@override
State<Sample> createState() => _SampleState();
}
class _SampleState extends State<Sample> {
@override
void initState() {
Provider.of<CategoriesProvider>(context, listen: false).getCatogories();
super.initState();
}
@override
Widget build(BuildContext context) {
var cat = Provider.of<CategoriesProvider>(context, listen: false).categories;
return Scaffold(
appBar: AppBar(),
drawer: const Drawer(),
body: Text("${cat?.data == null ? "there is no data" : cat!.statusCode}"),
);
}
}