How can I get data using provider? - flutter

I am implementing login with provider but I am not getting data on dashboard page.
Model Class
class LoginModel {
Data data;
int status;
String message;
LoginModel({this.data, this.status, this.message});
LoginModel.fromJson(Map<String, dynamic> json) {
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
status = json['status'];
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data.toJson();
}
data['status'] = this.status;
data['message'] = this.message;
return data;
}
}
class Data {
String customerId;
String customerMobileNo;
String customerToken;
String otp;
Data({this.customerId, this.customerMobileNo, this.customerToken, this.otp});
Data.fromJson(Map<String, dynamic> json) {
customerId = json['customerId'];
customerMobileNo = json['customerMobileNo'];
customerToken = json['customerToken'];
otp = json['otp'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['customerId'] = this.customerId;
data['customerMobileNo'] = this.customerMobileNo;
data['customerToken'] = this.customerToken;
data['otp'] = this.otp;
return data;
}
}
Provider Class
class AuthProvider extends ChangeNotifier {
Future<LoginModel> generateOTP(String mobileNumber) async {
var result;
Response response = await post(
AppUrl.login,
body: {
'mobileNo': mobileNumber,
},
);
if(response.statusCode==200) {
final responseData = json.decode(response.body);
var userData = responseData['data'];
print(responseData);
LoginModel authUser = LoginModel.fromJson(userData);
notifyListeners();
}
else {
print("Something went wrong");
}
return result;
}
}
Display Page
class Dashboard extends StatelessWidget {
#override
Widget build(BuildContext context) {
final userTest = Provider.of<AuthProvider>(context);
return Scaffold(
body: Center(
child: ListView(
shrinkWrap: true,
children: [
Text(userTest.authUser.data.customerToken),
],
),
),
);
}
Error
The following NoSuchMethodError was thrown while handling a gesture:
The getter 'customerToken' was called on null.
Receiver: null
Tried calling: customerToken
How can I access the property of LoginModel class. Can anyone solve my query please help me, I tried a lott but I can not get value.

You cannot notify your listeners with normal Future functions (though, I am not sure because you didn't provide the full code of your provider class). You will have to put your generateOTP() function in a changenotifier class that will help you to notify your listeners whenever required and make it scoped to your widget.
You are getting this error because you are not storing your token anywhere or you are not invoking your storage token before using it. So first, please try to store your token and invoke it before using it.

LoginModel authUser = LoginModel.fromJson(userData); you are initializing value to method variable LoginModel authUser not a class variable authUser try removing LoginModel from before 'authUser'.
In Dashboard you should also check for null value, you can do that like this userTest?.authUser?.data?.customerToken ?? ''

Related

How to cast parsed response from Model to a local variable in Flutter

I still like to call myself a novice when it comes to parsing a JSON response into a model class for usage. I have a certain JSON response which I have converted into a Model using one of those websites that does all the hard work. However, I repeatedly keep getting errors saying type 'LoginModel' is not a subtype of type 'Map<String, dynamic>' when I make the API Call. Here is the response followed by the code:
The JSON response:
{
"data": {
"access_token": "*********",
"role": 0,
"id": 000,
"lat": "0.0",
"lng": "0.0",
"radius": 200,
"department": "IIIII",
"approval": 1
}
}
This here is the Model class:
class LoginModel {
Data? data;
LoginModel({this.data});
LoginModel.fromJson(Map<String, dynamic> json) {
data = json['data'] != null ? Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data!.toJson();
}
return data;
}
}
class Data {
String? accessToken;
int? role;
int? id;
String? lat;
String? lng;
int? radius;
String? department;
int? approval;
Data(
{this.accessToken,
this.role,
this.id,
this.lat,
this.lng,
this.radius,
this.department,
this.approval});
Data.fromJson(Map<String, dynamic> json) {
accessToken = json['access_token'];
role = json['role'];
id = json['id'];
lat = json['lat'];
lng = json['lng'];
radius = json['radius'];
department = json['department'];
approval = json['approval'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['access_token'] = this.accessToken;
data['role'] = this.role;
data['id'] = this.id;
data['lat'] = this.lat;
data['lng'] = this.lng;
data['radius'] = this.radius;
data['department'] = this.department;
data['approval'] = this.approval;
return data;
}
}
The class where I get the error:
class LoginController with ChangeNotifier {
NetworkServices networkServices = NetworkServices();
Map<String, dynamic> _loginResponse = {}; //I would like to store the parsed response into this variable for local use
Map<String, dynamic> get loginResponse {
return _loginResponse;
}
Future<void> login(dynamic data, BuildContext context) async {
networkServices
.postLoginRequest(ApiUrl.loginUrl, data, context)
.then((value) {
_loginResponse =
LoginModel.fromJson(value['data']) as Map<String, dynamic>; //I'm pretty sure this is what I've done wrong
print('SUCCESS: $_loginResponse');
}).onError((error, stackTrace) {
// Loader(false);
print('ERRROR: $error'); //This is where the error gets printed after it comes from the NetworkServices class where the API Call is made
});
notifyListeners();
}
}
Network Class where the API gets called:
class NetworkServices {
Future<dynamic> postLoginRequest(
String url, dynamic data, BuildContext context) async {
var jsonResponse;
try {
final response = await http.post(Uri.parse(url),
body: json.encode(data),
headers: {
'Content-Type': 'application/json'
}).timeout(const Duration(seconds: 30));
jsonResponse = returnResponse(response);
print('FROM NETWORK: $jsonResponse');
} on SocketException {
Flushbar(
leftBarIndicatorColor: Colors.red,
icon: const Icon(Icons.warning, color: Colors.white),
message: 'Ooops!!! Something went wrong',
).show(context);
}
return jsonResponse;
}
dynamic returnResponse(http.Response response) {
if (response.statusCode >= 200 && response.statusCode <= 300) {
dynamic jsonResponse = json.decode(response.body);
return jsonResponse;
} else if (response.statusCode >= 400 || response.statusCode == 404) {
return 'An Error Occured';
} else if (response.statusCode >= 404) {
return 'Invalid Request';
} else {
return 'Error Occured While Communicating with Servers!!! Please try again later';
}
}
}
Problems:
You are casting the LoginModel object returned from LoginModel.fromJson(...) as a Map<String, dynamic> instead of casting value['data'] as Map<String, dynamic>.
You are also assigning the LoginModel.fromJson(...) to a variable of type Map<String, dynamic>, _loginResponse.
Solution:
Change this line of code:
_loginResponse = LoginModel.fromJson(value['data']) as Map<String, dynamic>;
to this:
_loginResponse = value['data'] as Map<String, dynamic>;
Update:
In other to store the login information in the LoginModel, you need to make the following to the LoginController class:
Make the _loginResponse variable a LoginModel instead of a Map<String, dynamic>
Make the loginResponse getter return a LoginModel object instead of a Map<String, dynamic>
Cast value['data'] to a Map<String, dynamic> and pass it into LoginModel.fromJson(...)
Your updated LoginController class will be:
class LoginController with ChangeNotifier {
NetworkServices networkServices = NetworkServices();
LoginModel _loginResponse = LoginModel();
LoginModel get loginResponse {
return _loginResponse;
}
Future<void> login(dynamic data, BuildContext context) async {
networkServices
.postLoginRequest(ApiUrl.loginUrl, data, context)
.then((value) {
_loginResponse =
LoginModel.fromJson(value['data'] as Map<String, dynamic>);
print('SUCCESS: $_loginResponse');
}).onError((error, stackTrace) {
// Loader(false);
print('ERRROR: $error');
});
notifyListeners();
}
}

type 'Null' is not a subtype of type 'List<dynamic>' in type cast in flutter

I am trying to fetch image from an api. For that I am using http package for flutter. I created Model View Controller pattern to arrange the structure of the project. Here is the api link and response:
https://wrestlingworld.co/wp-json/wp/v2/posts/128354
Response =>
[{"id":128640,"date":"2022-11-04T15:09:58","date_gmt":"2022-11-04T09:39:58","guid":{"rendered":"https:\/\/wrestlingworld.co\/?p=128640"},"modified":"2022-11-04T15:10:04","modified_gmt":"2022-11-04T09:40:04","slug":"impact-knockouts-tag-team-championship-match-announced-for-over-drive-2022","status":"publish","type":"post","link":"https:\/\/wrestlingworld.co\/news\/impact-knockouts-tag-team-championship-match-announced-for-over-drive-2022","title":{"rendered":"Impact Knockouts Tag Team Championship Match Announced for Over Drive"},"content":{"rendered":"\n<p>Impact Knockouts Tag Team Championships will be on the line at Over Drive on November 18th. It has <a href=\"https:\/\/impactwrestling.com\/2022\/11\/03\/tasha-steelz-savannah-evans-look-to-topple-the-death-dollz-in-knockouts-world-tag-team-title-showdown-at-over-drive\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">been announced<\/a> that Death Dollz (Taya Valkyrie and Jessicka) will be defending their titles against Tasha Steelz and Savannah
Here is my model:
class NewsModel {
int? id;
String? date;
String? slug;
String? status;
Title? title;
Title? content;
List<OgImage>? ogImage;
int? author;
NewsModel(
{this.id,
this.date,
this.slug,
this.status,
this.title,
this.content,
this.ogImage,
this.author});
NewsModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
date = json['date'];
slug = json['slug'];
status = json['status'];
title = json['title'] != null ? new Title.fromJson(json['title']) : null;
content =
json['content'] != null ? new Title.fromJson(json['content']) : null;
if (json['og_image'] != null) {
ogImage = <OgImage>[];
json['og_image'].forEach((v) {
ogImage!.add(new OgImage.fromJson(v));
});
}
author = json['author'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['date'] = this.date;
data['slug'] = this.slug;
data['status'] = this.status;
if (this.title != null) {
data['title'] = this.title!.toJson();
}
if (this.content != null) {
data['content'] = this.content!.toJson();
}
if (this.ogImage != null) {
data['og_image'] = this.ogImage!.map((v) => v.toJson()).toList();
}
data['author'] = this.author;
return data;
}
}
class Title {
String? rendered;
Title({this.rendered});
Title.fromJson(Map<String, dynamic> json) {
rendered = json['rendered'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['rendered'] = this.rendered;
return data;
}
}
class OgImage {
String? url;
OgImage({this.url});
OgImage.fromJson(Map<String, dynamic> json) {
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['url'] = this.url;
return data;
}
}
Here you can see OgImage is a list So I created a card and tried this code:
final int id;
final String title;
final String description;
final List<dynamic> img;
const NewsCard({
required this.id,
required this.title,
required this.description,
required this.img,
});
ListView.builder(
itemCount: img.length,
itemBuilder: (context, item){
return Image.network(
img[item],
height: 120,
width: double.infinity
);
},
),
Here is the front end code where I am passing value :
Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: allNews.length,
itemBuilder: (context, i) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: NewsCard(
id: allNews[i].id as int,
title: allNews[i].title!.rendered!,
description: allNews[i].content!.rendered!,
img: allNews[i].ogImage?[0].url as List<dynamic>,
),
);
}),),
Here is my controller :
Future<bool> getNews() async {
var url = Uri.parse(urlnews);
// var token = storage.getItem('token');
try {
http.Response response = await http.get(url);
print(response.body);
var data = json.decode(response.body) as List;
// print(data);
List<NewsModel> temp = [];
data.forEach((element) {
NewsModel product = NewsModel.fromJson(element);
temp.add(product);
});
_news = temp;
notifyListeners();
return true;
} catch (e) {
print(e);
return false;
}
}
List<NewsModel> get allNews {
return [..._news];
}
This code has errors I mentioned in the title already. Here I have a qustion like how can I pass list value inside the card. What is right way to fetch lists of image inside a widget.
There are a few issues with your code:
1. In your NewsModel class file, you're mapping it all wrong.
You're mapping json['og_image'] to a List, while json['og_image'] doesn't exist in the first place. If you see the JSON response, instead it's within the json['yoast_head_json'] key. So, instead of json['og_image'] you need to do json['yoast_head_json']['og_image'].
Change:
if (json['og_image'] != null) {
ogImage = <OgImage>[];
json['og_image'].forEach((v) {
ogImage!.add(new OgImage.fromJson(v));
});
}
to:
if (json['yoast_head_json'] != null &&
json['yoast_head_json']['og_image'] != null) {
ogImage = <OgImage>[];
json['yoast_head_json']['og_image'].forEach((v) {
ogImage!.add(OgImage.fromJson(v));
});
2. In your frontend part, you're trying to cast a nullable type of list allNews[i].ogImage?[0].url as List<dynamic> to List<dynamic>, which will throw exception in case the list is NULL which is in your case.
so, instead of:
img: allNews[i].ogImage?[0].url as List<dynamic>
do:
img: allNews[i].ogImage ?? []
3. Finally, in your NewsCard class:
Change:
Image.network(
img[item],
...
);
to
Image.network(
img[item].url,
...
);
Enjoy :)

Why is GetConnect/GetX/Flutter not calling my backend and returning a null object?

I'm using get: 4.6.5
I have defined a provider
class CredentialsProvider extends GetConnect implements GetxService {
#override
void onInit() {
httpClient.defaultDecoder =
(val) => Auth.fromJson(val as Map<String, dynamic>);
httpClient.baseUrl = 'http://localhost:1337/api/';
super.onInit();
}
Future<Response<dynamic>> postCredentials(Credentials credentials) async {
return await post('auth/local', credentials);
}
}
In my binding class add it as a dependency
class LoginBinding extends Bindings {
#override
void dependencies() {
Get.lazyPut(() => CredentialsProvider());
Get.lazyPut(() => LoginController());
}
}
And register the LoginView as a route
GetPage(
name: "/login",
page: () => const LoginView(),
binding: LoginBinding(),
)
And added it to my controller
class LoginController extends GetxController {
final provider = Get.put(CredentialsProvider());
//...
}
The controller is used in my LoginView
class LoginView extends GetView<LoginController> {...}
In my MaterialButton of the LoginView I use the onPressed to call the provider and get the result object Auth and print it out as json.
onPressed: () {
var c = Credentials(
identifier: controller.emailController.text,
password: controller.passwordController.text);
controller.provider.postCredentials(c).then((value) {
var auth = value.body as Auth;
print(auth.toJson());
});
},
I generated my Auth model from JSON using the GetX cli:
class Auth {
String? jwt;
User? user;
Auth({this.jwt, this.user});
Auth.fromJson(Map<String, dynamic> json) {
jwt = json['jwt'];
user = json['user'] != null ? User?.fromJson(json['user']) : null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['jwt'] = jwt;
if (user != null) {
data['user'] = user?.toJson();
}
return data;
}
}
class User {
int? id;
String? username;
String? email;
String? provider;
bool? confirmed;
bool? blocked;
String? createdAt;
String? updatedAt;
User(
{this.id,
this.username,
this.email,
this.provider,
this.confirmed,
this.blocked,
this.createdAt,
this.updatedAt});
User.fromJson(Map<String, dynamic> json) {
id = json['id'];
username = json['username'];
email = json['email'];
provider = json['provider'];
confirmed = json['confirmed'];
blocked = json['blocked'];
createdAt = json['createdAt'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['id'] = id;
data['username'] = username;
data['email'] = email;
data['provider'] = provider;
data['confirmed'] = confirmed;
data['blocked'] = blocked;
data['createdAt'] = createdAt;
data['updatedAt'] = updatedAt;
return data;
}
}
What I get in the console is
flutter: {jwt: null}
And my localhost service is never called.
The issue was with the decoder for the request being different that for the response. So I ended up with something like this:
Future<Auth> postCredentials(Map<String, dynamic> body) async {
var response = await post(
contentType: 'application/json',
decoder: (val) => Auth.fromJson(val as Map<String, dynamic>),
"/api/auth/local",
body);
return response.body as Auth;
}
And I call this via
controller.provider.postCredentials(credentials.toJson());

How to register multiple adapters with hive for single modal class

I am kind of new to flutter and working on the application where I need to save data locally to use it later when user will be offline.
I have a modal class with multiple inner classes:
Modal Class:
import 'package:hive/hive.dart';
part 'DownloadResponse.g.dart';
#HiveType(typeId: 1)
class DownloadResponse extends HiveObject {
#HiveField(0)
UserInfo userInfo;
#HiveField(1)
AppSetting appSetting;
#HiveField(2)
List<Seals> seals;
#HiveField(3)
String success;
#HiveField(4)
String message;
DownloadResponse(
{this.userInfo, this.appSetting, this.seals, this.success, this.message});
DownloadResponse.fromJson(Map<String, dynamic> json) {
userInfo = json['userInfo'] != null
? new UserInfo.fromJson(json['userInfo'])
: null;
appSetting = json['appSetting'] != null
? new AppSetting.fromJson(json['appSetting'])
: null;
if (json['seals'] != null) {
seals = new List<Seals>();
json['seals'].forEach((v) {
seals.add(new Seals.fromJson(v));
});
}
success = json['success'];
message = json['message'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.userInfo != null) {
data['userInfo'] = this.userInfo.toJson();
}
if (this.appSetting != null) {
data['appSetting'] = this.appSetting.toJson();
}
if (this.seals != null) {
data['seals'] = this.seals.map((v) => v.toJson()).toList();
}
data['success'] = this.success;
data['message'] = this.message;
return data;
}
}
#HiveType(typeId: 2)
class UserInfo extends HiveObject {
String fullName;
String mobileLastSyncDate;
UserInfo({this.fullName, this.mobileLastSyncDate});
UserInfo.fromJson(Map<String, dynamic> json) {
fullName = json['full_name'];
mobileLastSyncDate = json['mobile_last_sync_date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['full_name'] = this.fullName;
data['mobile_last_sync_date'] = this.mobileLastSyncDate;
return data;
}
}
#HiveType(typeId: 3)
class AppSetting extends HiveObject {
String appWebviewHeight;
String appScreenHeaderSealScan;
String appScreenHeaderSealInfo;
String appScreenHeaderPicture1;
String appScreenHeaderPicture2;
AppSetting(
{this.appWebviewHeight,
this.appScreenHeaderSealScan,
this.appScreenHeaderSealInfo,
this.appScreenHeaderPicture1,
this.appScreenHeaderPicture2});
AppSetting.fromJson(Map<String, dynamic> json) {
appWebviewHeight = json['app_webview_height'];
appScreenHeaderSealScan = json['app_screen_header_seal_scan'];
appScreenHeaderSealInfo = json['app_screen_header_seal_info'];
appScreenHeaderPicture1 = json['app_screen_header_picture_1'];
appScreenHeaderPicture2 = json['app_screen_header_picture_2'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['app_webview_height'] = this.appWebviewHeight;
data['app_screen_header_seal_scan'] = this.appScreenHeaderSealScan;
data['app_screen_header_seal_info'] = this.appScreenHeaderSealInfo;
data['app_screen_header_picture_1'] = this.appScreenHeaderPicture1;
data['app_screen_header_picture_2'] = this.appScreenHeaderPicture2;
return data;
}
}
#HiveType(typeId: 4)
class Seals extends HiveObject {
String sealId;
String sealHtml;
List<Documents> documents;
Seals({this.sealId, this.sealHtml, this.documents});
Seals.fromJson(Map<String, dynamic> json) {
sealId = json['seal_id'];
sealHtml = json['seal_html'];
if (json['documents'] != null) {
documents = new List<Documents>();
json['documents'].forEach((v) {
documents.add(new Documents.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['seal_id'] = this.sealId;
data['seal_html'] = this.sealHtml;
if (this.documents != null) {
data['documents'] = this.documents.map((v) => v.toJson()).toList();
}
return data;
}
}
#HiveType(typeId: 5)
class Documents extends HiveObject {
String documentId;
String documentName;
String documentLink;
Documents({this.documentId, this.documentName, this.documentLink});
Documents.fromJson(Map<String, dynamic> json) {
documentId = json['document_id'];
documentName = json['document_name'];
documentLink = json['document_link'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['document_id'] = this.documentId;
data['document_name'] = this.documentName;
data['document_link'] = this.documentLink;
return data;
}
}
And this is my logic where I am trying to save data in the hive:
// We get the current app directory
WidgetsFlutterBinding.ensureInitialized();
final appDocDir = await getApplicationDocumentsDirectory();
// We initialize Hive and we give him the current path
Hive
..init(appDocDir.path)
..registerAdapter(DownloadResponseAdapter());
var box = await Hive.openBox('driverData');
//box.put('ew32', DownloadResponse('BMW','test', 2002));
UserInfo userInfo = downloadResponse.userInfo;
AppSetting appSetting = downloadResponse.appSetting;
List<Seals> sealList = downloadResponse.seals;
String success = downloadResponse.success;
String message = downloadResponse.message;
await box.put('driverData', DownloadResponse()
..userInfo = userInfo
..appSetting = appSetting
..seals = sealList
..success = success
..message = message);
print(box.get('driverData'));
I get this exception when box.put() runs:
Unhandled Exception: HiveError: Cannot write, unknown type: UserInfo. Did you forget to register an adapter
My question is how do I create and add multiple adapters with hive as my modal class has multiple classes?
I got the answer of the same. You will have all the adapters available in the automated generated file.
You just need to add them before saving data like this:
Hive
..init(appDocDir.path)
..registerAdapter(DownloadResponseAdapter())
..registerAdapter(UserInfoAdapter())
..registerAdapter(AppSettingAdapter())
..registerAdapter(SealsAdapter())
..registerAdapter(DocumentsAdapter()
);

Add item to provider in flutter

What's the correct way to use provider with an api call?
My current setup, although I don't know if it's correct, is I have a response model and a Response class and the response model gets passed to the response class. the ui is using a provider. Heres's the code:
class InfoProvider extends ChangeNotifier {
Future<Response> getSomeInfo(SomeInfo someInfo) async {
try {
final responseJson = await _provider.post('/info', someInfo.toJson());
ResponseModel someResponse = ResponseModel.fromJson(responseJson['payload']);
return Response.success(someResponse);
} catch (e) {
if (e.toString() == 'refresh_token_not_found') return Response.unauthenticated();
return Response.error(e.getError());
}
}
Future<Response> fetchInfo() async {
try {
final responseJson = await _provider.get('info');
if (responseJson['payload'].isEmpty) return Response.success([]);
AllInfoResponse alLInfoResponse = AllInfoResponse.fromJson(responseJson['payload']);
_allInfo = alLInfoResponse.AllInfoResponse;
return Response.success(alLInfoResponse);
} catch (e) {
if (e.toString() == 'refresh_token_not_found') return Response.unauthenticated();
return Response.error(e.toString());
}
}
}
The ui has a future builder like this: future: Provider.of<InfoProvider>(context).getSomeInfo(),
So that all works, but how can I add some more items to the ui?
Here's my model:
class ResponseModel {
final List<SingleResponseModel> ResponseModel;
ResponseModel({this.ResponseModel});
factory ResponseModel.fromJson(List<dynamic> json) => ResponseModel(
ResponseModel: List<SingleResponseModel>.from(json.map((x) => SingleResponseModel.fromJson(x))),
);
}
class SingleResponseModel {
final String id;
final String title;
SingleResponseModel({
this.id,
this.title,
});
factory SingleResponseModel.fromJson(Map<String, dynamic> json) {
return SingleResponseModel(
id: json['_id'],
title: json['title'],
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['title'] = this.title;
return data;
}
}
The best way to do this in your scenario is to wrap MaterialApp inside MyApp() in your main.dart file with MultiProvider. Try something like this: https://pub.dev/packages/provider#multiprovider You can place a ChangeNotifierProvider inside it.
Here is how you can access the values of ResponseModel in your UI:
final model=Provider.of<ResponseModel>(context,listen:false);
Don't forget to add getters and setters so that you can use notifyListeners() if you have any ui that depends on it.
This is how your model should look like:
class ResponseModel extends ChangeNotifier {
List<SingleResponseModel> _myModel;
get myModel => _myModel;
set myModel(List<SingleResponseModel> myModel) {
_myModel = myModel;
notifyListeners();
}
}
Here is how you can display your data in a Text Widget (Ideally, you should use Selector instead of Consumer so that the widget only rebuilds if the value its listening to changes):
#override
Widget build(BuildContext context) {
//other widgets
Selector<ResponseModel, int>(
selector: (_, model) => model.myModel,
builder: (_, model, __) {
return ListView.builder(
itemCount: model.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(model[index].title),
subtitle:Text(model[index].id),
);
},
);
}
)
}
Hope this helps! Good Luck!