I'm carrying out a basic fetch API request in the code below. The response I'm receiving gives the values for most of the properties except for two which come as null. This has me thinking if it is my code that's causing this issue to occur or something on the backend side which results into this anomaly. As shown below, the fiels that come as null in my VS Code terminal are product_description and restaurant_id. Although these come as null when displayed on the terminal, on Postman it is a different story as the response comes in full. The code and the responses are as follows:
Response on Postman:
{
"status": "success",
"data": [
{
"product_id": 8,
"restaurant_name": "Mocambo",
"restaurant_id": "6", //This is the field in question
"product_name": "Kaju Paneer",
"product_description": "Tasty yummy paneer gravy dish", //And So is this
"product_image": "/public/assets/product/lgml5L03-19-41.jpg",
"product_selling_price": "320"
}
]
}
Response received on Terminal after API Call:
{"status":"success","data":[{"product_id":8,"restaurant_name":"Mocambo","restaurant_id":"6","product_name":"Kaju Paneer","product_description":"Tasty yummy paneer gravy dish","product_image":"\/public\/assets\/product\/lgml5L03-19-41.jpg","product_selling_price":"320"}
When I try printing all the properties this is what I get(You can see above that I still receive data for restaurant_id and product_description)
I/flutter (10235): Provider product_selling_price 320
I/flutter (10235): Provider product_image /public/assets/product/lgml5L03-19-41.jpg
I/flutter (10235): Provider product_name Kaju Paneer
I/flutter (10235): Provider product_id 8
I/flutter (10235): Provider restaurantName Mocambo
I/flutter (10235): Provider Restaurant ID null //Restaurant ID here comes as null
I/flutter (10235): Provider Restaurant Description null //Restaurant Description comes as null
The codes for the Model Class, the class from which the API is called and the widget where it is used are below:
Model Class
import 'package:meta/meta.dart';
import 'dart:convert';
PopularDishes popularDishesFromJson(String str) =>
PopularDishes.fromJson(json.decode(str));
String popularDishesToJson(PopularDishes data) =>
json.encode(data.toJson());
class PopularDishes {
PopularDishes ({
required this.status,
required this.data,
});
String status;
List<Datum> data;
factory PopularDishes .fromJson(Map<String, dynamic> json) =>
PopularRestaurants(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
required this.productId,
required this.restaurantName,
required this.restaurantId,
required this.productName,
required this.productDescription,
required this.productImage,
required this.productSellingPrice,
});
int productId;
String restaurantName;
String restaurantId;
String productName;
String productDescription;
String productImage;
String productSellingPrice;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
productId: json["product_id"],
restaurantName: json["restaurant_name"],
restaurantId: json["restaurant_id"],
productName: json["product_name"],
productDescription: json["product_description"],
productImage: json["product_image"],
productSellingPrice: json["product_selling_price"],
);
Map<String, dynamic> toJson() => {
"product_id": productId,
"restaurant_name": restaurantName,
"restaurant_id": restaurantId,
"product_name": productName,
"product_description": productDescription,
"product_image": productImage,
"product_selling_price": productSellingPrice,
};
}
The class from where the API is called
class PopularDishesProvider with ChangeNotifier {
Map<String, dynamic> _popularDishes = {};
String baseUrl = 'https://achievexsolutions.in/current_work/eatiano/';
Map<String, dynamic> get popularDishes {
return {..._popularDishes};
}
Future<void> fetchData() async {
final url = Uri.parse(baseUrl + 'api/all_products');
final response = await http.get(url);
print(response.body);
PopularDishes popularDishes = popularDishesFromJson(response.body);
_popularDishes = popularDishes.toJson();
// print(_popularDishes);
}
}
The widget
class PopularDishes extends StatefulWidget {
PopularDishesState createState() => PopularDishesState();
}
class PopularDishesState extends State<PopularDishes> {
bool _isLoading = true;
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
Provider.of<PopularDishesProvider>(context).fetchData().then((_) {
setState(() {
_isLoading = false;
});
});
}
#override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;
var textScale = MediaQuery.of(context).textScaleFactor * 1.1;
var subTitleScale = MediaQuery.of(context).textScaleFactor * 1.4;
final provider = Provider.of<PopularDishesProvider>(context).popularDishes;
print(
'Provider product_selling_price ${provider['data'][0]['product_selling_price']}');
print('Provider product_image ${provider['data'][0]['product_image']}');
print('Provider product_name ${provider['data'][0]['product_name']}');
print('Provider product_id ${provider['data'][0]['product_id']}');
print('Provider restaurantName ${provider['data'][0]['restaurant_name']}');
print('Provider Restaurant ID ${provider['data'][0]['restaurant_id']}'); //Returns null here
print(
'Provider Restaurant Description ${provider['data'][0]['product_description']}'); //Returns null here
}
}
Is there anything I can do to fix this or is this a backend issue?
It may happen if some of your restaurant_id contains null value. If you are getting the response of data Try as follows:
provider['data'][0]['restaurant_id']==null?
print("isEmpty") :
print('Provider Restaurant ID ${provider['data'][0]['restaurant_id']}');
Note, I could not check your Model class because you did not provide PopularRestaurants. Also, I may be mistaken but I don't think you should make async-await function calls inside provider. First call fetchData in your StatefulWidget, then save the data in your provider. I also think you're using didChangeDependencies wrong and what you want is initstate.
This works for me:
Model Class generated from https://javiercbk.github.io/json_to_dart/
class PopularDishesModel {
String? status;
List<Data>? data;
PopularDishesModel({this.status, this.data});
PopularDishesModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = status;
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
int? productId;
String? restaurantName;
String? restaurantId;
String? productName;
String? productDescription;
String? productImage;
String? productSellingPrice;
Data(
{this.productId,
this.restaurantName,
this.restaurantId,
this.productName,
this.productDescription,
this.productImage,
this.productSellingPrice});
Data.fromJson(Map<String, dynamic> json) {
productId = json['product_id'];
restaurantName = json['restaurant_name'];
restaurantId = json['restaurant_id'];
productName = json['product_name'];
productDescription = json['product_description'];
productImage = json['product_image'];
productSellingPrice = json['product_selling_price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['product_id'] = productId;
data['restaurant_name'] = restaurantName;
data['restaurant_id'] = restaurantId;
data['product_name'] = productName;
data['product_description'] = productDescription;
data['product_image'] = productImage;
data['product_selling_price'] = productSellingPrice;
return data;
}
}
This is my stateful widget
class PopularDishes extends StatefulWidget {
PopularDishesState createState() => PopularDishesState();
}
class PopularDishesState extends State<PopularDishes> {
String baseUrl = 'https://achievexsolutions.in/current_work/eatiano/';
//Initialize PopularDishesModel
PopularDishesModel savedModel = PopularDishesModel();
//Make sure all json is downloaded
bool _isLoading = true;
//Remove this function from provider and put in your widget
Future<PopularDishesModel> fetchData() async {
final url = Uri.parse(baseUrl + 'api/all_products');
final response = await http.get(url);
//print(response.body);
PopularDishesModel popularDishes = PopularDishesModel.fromJson(json.decode(response.body));
return popularDishes;
}
//This is an async function f
void GetRestaurantData() async
{
PopularDishesModel result = await fetchData();
setState(() {
savedModel = result;
_isLoading = false;
});
}
#override
void initState() {
super.initState();
GetRestaurantData();
}
#override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;
var textScale = MediaQuery.of(context).textScaleFactor * 1.1;
var subTitleScale = MediaQuery.of(context).textScaleFactor * 1.4;
//Add code to save to provider
if(_isLoading == false) {
print(savedModel.data![0].productId);
print(savedModel.data![0].restaurantName);
print(savedModel.data![0].restaurantId);
print(savedModel.data![0].productName);
print(savedModel.data![0].productDescription);
print(savedModel.data![0].productImage);
print(savedModel.data![0].productSellingPrice);
/*Result
8
Mocambo
6
Kaju Paneer
Tasty yummy paneer gravy dish
/public/assets/product/lgml5L03-19-41.jpg
320*/
}
//Add logic to save to provider
return Container();
}
}
Related
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());
I am trying to retrieve data from Firebase Realtime Database into a list in Flutter using a model.I don't get snapshot.data how to get data.value. I have read several other posts about using Firebase with Flutter but have not found a clear answer.
Model class screen:
import 'package:firebase_database/firebase_database.dart';
class DataModel {
final String id;
final String name;
final String price;
final String qty;
DataModel(
{required this.id,
required this.name,
required this.price,
required this.qty});
DataModel.fromSnapshot(DataSnapshot snapshot)
: id = snapshot.key.toString(),
name = (snapshot.value as Map<String, dynamic>?)?['productName'] ?? '',
price =
(snapshot.value as Map<String, dynamic>?)?['productPrice'] ?? '',
qty = (snapshot.value as Map<String, dynamic>?)?['qty'] ?? '';
toJson() {
return {
"productName": name,
"productPrice": price,
"qty": qty,
};
}
}
Database service with Firebase query:
import 'package:firebase_database/firebase_database.dart';
import 'package:money_management/data_json_model.dart';
class DatabaseService {
static List<DataModel> getData() {
Query needsSnapshot =
FirebaseDatabase.instance.ref("Money Management").orderByKey();
// print(needsSnapshot); // to debug and see if data is returned
List<DataModel> needs = [];
Map<dynamic, dynamic> values = needsSnapshot.onValue as Map;
values.forEach((key, values) {
needs.add(DataModel.fromSnapshot(values));
});
return needs;
}
}
ListView Page:
import 'package:flutter/material.dart';
import 'package:money_management/data_json_model.dart';
import 'database_service.dart';
class ListScreen extends StatefulWidget {
const ListScreen({Key? key}) : super(key: key);
#override
State<ListScreen> createState() => _ListScreenState();
}
class _ListScreenState extends State<ListScreen> {
List<DataModel> _needs = [];
#override
void initState() {
super.initState();
_setupNeeds();
}
_setupNeeds() async {
List<DataModel> needs = DatabaseService.getData();
setState(() {
_needs = needs;
});
}
#override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () => _setupNeeds(),
child: ListView.builder(
itemCount: _needs.length,
itemBuilder: (BuildContext context, int index) {
DataModel need = _needs[index];
return Column(
children: [
Text(need.id),
Text(need.name),
Text(need.price),
Text(need.qty),
],
);
}),
);
}
}
Try make the method getData() asynchronous and call get() of FirebaseDatabase instead:
class DatabaseService {
static Future<List<dynamic>> getData() async {
final snapshot = await FirebaseDatabase.instance
.ref("Money Management")
.orderByKey()
.get();
// print(snapshot); // to debug and see if data is returned
List<DataModel> needs = [];
Map<dynamic, dynamic> values = snapshot.value as Map;
values.forEach((key, values) {
needs.add(DataModel.fromSnapshot(values));
});
return needs;
}
}
you can receive data as Map<String,dynamic> in your DataModel like this:
class DataModel {
late String id;
late String name;
late String price;
late String qty;
DataModel({
required this.id,
required this.name,
required this.price,
required this.qty
});
DataModel.fromSnapshot(DataSnapshot snapshot){
Map<String, dynamic> myData= Map<String,dynamic>.from(snapshot.value as
Map);
id = snapshot.key.toString();
name = myData["productName"].toString() ?? '';
price =myData["productPrice"].toString() ?? '';
qty = myData["qty"].toString() ?? '';
}
Map<String,dynamic> toJson() {
return {
"productName": name,
"productPrice": price,
"qty": qty,
};
}
}
This is my model class and I am trying to get all the data but getting error and don't know why.
HomePageModel homePageModelFromJson(String str) => HomePageModel.fromJson(json.decode(str));
String homePageModelToJson(HomePageModel data) => json.encode(data.toJson());
class HomePageModel with ChangeNotifier {
HomePageModel({
this.data,
});
List<Datum>? data;
factory HomePageModel.fromJson(Map<String, dynamic> json) => HomePageModel(
data: List<Datum>.from(json["data"]!.map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data!.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.schoolid,
this.name,
this.logo,
this.address,
this.contact,
this.principalname,
this.principalcontact,
this.slogan,
this.webAddress,
this.description,
this.email,
this.pan,
this.establishedYear,
});
String? schoolid;
String? name;
String? logo;
String? address;
String? contact;
String? principalname;
String? principalcontact;
String? slogan;
String? webAddress;
String? description;
String? email;
String? pan;
int? establishedYear;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
schoolid: json["schoolid"],
name: json["name"],
logo: json["logo"],
address: json["address"],
contact: json["contact"],
principalname: json["principalname"],
principalcontact: json["principalcontact"],
slogan: json["slogan"],
webAddress: json["web_address"] == null ? null : json["web_address"],
description: json["description"] == null ? null : json["description"],
email: json["email"],
pan: json["pan"],
establishedYear: json["established_year"],
);
Map<String, dynamic> toJson() => {
"schoolid": schoolid,
"name": name,
"logo": logo,
"address": address,
"contact": contact,
"principalname": principalname,
"principalcontact": principalcontact,
"slogan": slogan,
"web_address": webAddress == null ? null : webAddress,
"description": description == null ? null : description,
"email": email,
"pan": pan,
"established_year": establishedYear,
};
}
This is how I am trying to fetch data:
class HomePageModels with ChangeNotifier{
List<HomePageModel> _hItem = [];
List<HomePageModel> get hItem{
return [..._hItem];
}
Future<void> getHomeData(BuildContext context) async{
const url = "https://shikshyasoftware.com.np/CoreApplicationandAPIService-4617993073/api/school";
try{
// EasyLoading.show(status: 'Loading...');
final response = await http.get(Uri.parse(url));
final extractedData = json.decode(response.body);
List<HomePageModel> loadedHomeData = [];
if(extractedData == null){
return;
}
if(response.statusCode == 200){
print(extractedData);
}
extractedData.forEach((element){
loadedHomeData.add(HomePageModel.fromJson(element));
});
_hItem = loadedHomeData;
// EasyLoading.showSuccess("data fetched sucessfull");
notifyListeners();
}catch(e){
rethrow;
}
}
}
But I am getting error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type '(dynamic) => Null' is not a subtype of type '(String, dynamic) => void' of 'f'
The problem is the way you are trying to parse the data, you don't need to loop over every element to parse it, in your model just make it return a list type like this,
class HomePageModel with ChangeNotifier {
List<Datum>? data;
HomePageModel({this.data});
HomePageModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
data = <Datum>[];
json['data'].forEach((v) {
data!.add(new Datum.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Datum {
Datum({
this.schoolid,
this.name,
this.logo,
this.address,
this.contact,
this.principalname,
this.principalcontact,
this.slogan,
this.webAddress,
this.description,
this.email,
this.pan,
this.establishedYear,
});
String? schoolid;
String? name;
String? logo;
String? address;
String? contact;
String? principalname;
String? principalcontact;
String? slogan;
String? webAddress;
String? description;
String? email;
String? pan;
int? establishedYear;
Datum.fromJson(Map<String, dynamic> json) {
schoolid = json["schoolid"];
name = json["name"];
logo = json["logo"];
address = json["address"];
contact = json["contact"];
principalname = json["principalname"];
principalcontact = json["principalcontact"];
slogan = json["slogan"];
webAddress = json["web_address"];
description = json["description"];
email = json["email"];
pan = json["pan"];
establishedYear = json["established_year"];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['schoolid'] = this.schoolid;
data['name'] = this.name;
data['logo'] = this.logo;
data['address'] = this.address;
data['contact'] = this.contact;
data['principalname'] = this.principalname;
data['principalcontact'] = this.principalcontact;
data['slogan'] = this.slogan;
data['web_address'] = this.webAddress;
data['description'] = this.description;
data['email'] = this.email;
data['pan'] = this.pan;
data['established_year'] = this.establishedYear;
return data;
}
}
and in your view model you can just parse the extracted data from response.body like this,
class HomePageModels with ChangeNotifier {
HomePageModel? _hItem;
HomePageModel get hItem {
return _hItem!;
}
Future<void> getHomeData(BuildContext context) async {
const url =
"https://shikshyasoftware.com.np/CoreApplicationandAPIService-
4617993073/api/school";
try {
// EasyLoading.show(status: 'Loading...');
final response = await http.get(Uri.parse(url));
final extractedData = json.decode(response.body);
if (extractedData == null) {
return;
}
if (response.statusCode == 200) {
print(extractedData);
}
HomePageModel loadedHomeData =
HomePageModel.fromJson(extractedData);
_hItem = loadedHomeData;
// EasyLoading.showSuccess("data fetched sucessfull");
notifyListeners();
} catch (e) {
rethrow;
}
}
}
getHomeData(BuildContext context) async {
const url =
"https://shikshyasoftware.com.np/CoreApplicationandAPIService-4617993073/api/school";
try {
// EasyLoading.show(status: 'Loading...');
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final extractedData = json.decode(response.body);
List loadedHomeData = extractedData;
_hItem = loadedHomeData.map((e) => HomePageModel.fromJson(e)).toList();
}
notifyListeners();
return _hItem;
} catch (e) {
rethrow;
}
}
I have an application with news api from https://newsapi.org/
My model from quicktype:
// To parse this JSON data, do
//
// final news = newsFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
List<News> newsFromJson(String str) =>
List<News>.from(json.decode(str).map((x) => News.fromJson(x)));
String newsToJson(List<News> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class News {
News({
required this.status,
required this.totalResults,
required this.articles,
});
final String status;
final int totalResults;
final List<Article> articles;
factory News.fromJson(Map<String, dynamic> json) => News(
status: json["status"],
totalResults: json["totalResults"],
articles: List<Article>.from(
json["articles"].map((x) => Article.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"totalResults": totalResults,
"articles": List<dynamic>.from(articles.map((x) => x.toJson())),
};
}
class Article {
Article({
required this.source,
required this.author,
required this.title,
required this.description,
required this.url,
required this.urlToImage,
required this.publishedAt,
required this.content,
});
final Source source;
final String author;
final String title;
final String description;
final String url;
final String urlToImage;
final DateTime publishedAt;
final String content;
factory Article.fromJson(Map<String, dynamic> json) => Article(
source: Source.fromJson(json["source"]),
author: json["author"] == null ? null : json["author"],
title: json["title"],
description: json["description"],
url: json["url"],
urlToImage: json["urlToImage"],
publishedAt: DateTime.parse(json["publishedAt"]),
content: json["content"],
);
Map<String, dynamic> toJson() => {
"source": source.toJson(),
"author": author == null ? null : author,
"title": title,
"description": description,
"url": url,
"urlToImage": urlToImage,
"publishedAt": publishedAt.toIso8601String(),
"content": content,
};
}
class Source {
Source({
required this.id,
required this.name,
});
final String id;
final String name;
factory Source.fromJson(Map<String, dynamic> json) => Source(
id: json["id"] == null ? null : json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
"name": name,
};
}
In my remoteservice.dart:
import 'package:http/http.dart' as http;
import 'package:nocovid/models/news.dart';
import 'package:nocovid/utils/constant.dart';
class RemoteServices {
static var client = http.Client();
static Future<List<News>?> fetchNews() async {
final String endpoint =
'https://newsapi.org/v2/everything?q=covid19&apiKey=' + kAPIKey;
final Uri url = Uri.parse(endpoint);
final response = await client.get(url);
if (response.statusCode == 200) {
var jsonString = response.body;
return newsFromJson(jsonString);
} else {
return null;
}
}
}
newscontroller.dart
import 'package:get/state_manager.dart';
import 'package:nocovid/models/news.dart';
import 'package:nocovid/services/remote_services.dart';
class NewsController extends GetxController {
var newsList = <News>[].obs;
#override
void onInit() {
fetchNews();
super.onInit();
}
void fetchNews() async {
var news = await RemoteServices.fetchNews();
if (news != null) {
newsList.value = news;
}
}
}
And get this errors:
and
the call is performed regularly but upon showing the data, it generates these errors.
I checked some codes on github and everything seems to work, while i can't get going
Change
List<News> newsFromJson(String str) =>
List<News>.from(json.decode(str).map((x) => News.fromJson(x)));
To
News newsFromJson(String str) => News.fromJson(json.decode(str));
The Reason for this is News object is not a list, it's a complex JSON with a map that consists of a list of Articles. You need to go through API properly.
If you want a model you can use quicktype. Just paste in the URL response.
Also Change
static Future<List<News>?> fetchNews()
to
static Future<News> fetchNews()
I want to showing this value to listview on flutter
[{"No":0,"interest":"0.00","balance":"13,000,000.00","principal":"0.00","Installment":"0.00","Status":true},{"No":1,"interest":"130,000.00","balance":"0.00","principal":"13,000,000.00","Installment":"13,130,000.00","Status":true}]
but i get the result like
I/flutter (12074): Error FormatException: Unexpected character (at character 1)
I/flutter (12074): <br />
I/flutter (12074): ^
I/flutter (12074):
here is my List LoanModel
static Future<List<LoanModel>> getsimulation({String periodtime, String interestpermonth, String loanamountrequest, String idUser, String url}) async {
var url = "http://192.168.0.23/edufund-api/Api/loansimulation.php?periodtime=" + periodtime + "&interestpermonth=" + interestpermonth + "&loanamountrequest=" +loanamountrequest;
final response = await http.get(url,headers:{"Content-Type":
"application/json"});
var res = LoanModel.fromJson(jsonDecode(response.body)[0]);
print(response.body);
}
here is the function to load JSON when already input value periodtime, interestpermonth and loanamountrequest
_load() async {
List<LoanModel> loanmodel =
(await RestApi.getsimulation());
setState(() => _loanmodel = loanmodel);
}
Here is my Model
List<LoanModel> allLoan(String str) {
final jsonData = json.decode(str);
return new List<LoanModel>.from(jsonData.map((x) => LoanModel.fromJson(x)));
}
class LoanModel {
bool Status;
String message;
String No;
String interest;
String balance;
String principal;
String Installment;
List<Data> data;
LoanModel({
this.Status,
this.message,
this.No,
this.interest,
this.balance,
this.principal,
this.Installment,
this.data,
});
factory LoanModel.fromJson(Map<String, dynamic> parsedJson) {
var list = parsedJson['data'] as List;
print(list.runtimeType);
List<Data> dataList = list.map((i) => Data.fromJson(i)).toList();
return LoanModel(
Status: parsedJson['Status'],
message: parsedJson['message'],
No : parsedJson['No'],
interest: parsedJson['interest'],
balance: parsedJson['balance'],
principal: parsedJson['principal'],
Installment: parsedJson['Installment'],
data: dataList,
);
}
}
class Data {
final int No;
final String interest;
final String balance;
final String principal;
final String Installment;
Data({
this.No,
this.interest,
this.balance,
this.principal,
this.Installment
});
factory Data.fromJson(Map<String, dynamic> parsedJson) {
return Data(
No: parsedJson['No'],
interest: parsedJson['interest'],
balance: parsedJson['balance'],
principal: parsedJson['principal'],
Installment: parsedJson['Installment']
);
}
and the result is keep loading like this
The output should be like this
How can i make output like picture number 2 and how to resolved this Unexpected character in flutter?
thank you
I am able to parse it with the JSON locally. Update the dataModel:
import 'dart:convert';
List<LoanModel> loanModelFromJson(String str) => List<LoanModel>.from(json.decode(str).map((x) => LoanModel.fromJson(x)));
String loanModelToJson(List<LoanModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class LoanModel {
LoanModel({
this.no,
this.interest,
this.balance,
this.principal,
this.installment,
this.status,
});
int no;
String interest;
String balance;
String principal;
String installment;
bool status;
factory LoanModel.fromJson(Map<String, dynamic> json) => LoanModel(
no: json["No"],
interest: json["interest"],
balance: json["balance"],
principal: json["principal"],
installment: json["Installment"],
status: json["Status"],
);
Map<String, dynamic> toJson() => {
"No": no,
"interest": interest,
"balance": balance,
"principal": principal,
"Installment": installment,
"Status": status,
};
}
Any try to parse it like this:
arr = loanModelFromJson(response.body);
RestAPI call
class APIManager {
final String baseURL = [BaseURL];
getData(apiUrl) async {
var fullUrl = baseURL + apiUrl;
return await http.get(Uri.parse(fullUrl), headers: _setHeader());
}
}
Future<void> getData() async {
var response = await APIManager().getData([Endpoint]);
arr = loanModelFromJson(response.body);
}