I am working with GraphQL. I need to pass parameters to Http headers. However, I see an option to pass only normal parameters (code below). PLEASE tell me how to do it!!
Query(
options: QueryOptions(
document: gql(userGraphQL),
variables: {
"..." : "..."
}
),
builder: ...
)
I have created this file to related the GraphQL
gql_utils.dart file
class GraphQLUtils {
static final GraphQLUtils _instance = GraphQLUtils._internal();
GraphQLClient? _client;
factory GraphQLUtils() {
return _instance;
}
GraphQLUtils._internal() {
final httpLink = HttpLink(
'your base url',
);
final authLink = AuthLink(
ignore: undefined_identifier
getToken: () async => 'Bearer $YOUR_PERSONAL_ACCESS_TOKEN',
);
var link = authLink.concat(httpLink);
var link = httpLink;
var link = httpLink;
final policies = Policies(
fetch: FetchPolicy.networkOnly,
);
_client = GraphQLClient(
cache: GraphQLCache(),
link: link,
defaultPolicies: DefaultPolicies(
watchQuery: policies,
query: policies,
mutate: policies,
),
);
}
Future<Map<String, dynamic>> queryRepo(
DocumentNode readRepositories, map) async {
final options = WatchQueryOptions(
document: readRepositories,
variables: map,
pollInterval: const Duration(seconds: 4),
fetchResults: true,
);
QueryResult result = await _client!.query(options);
if (result.hasException) {
Map<String, dynamic> response = <String, dynamic>{};
response['success'] = false;
response['message'] = result.exception!.graphqlErrors[0].message;
return response;
} else {
Map<String, dynamic> response = <String, dynamic>{};
response['success'] = true;
response['data'] = result.data;
return response;
}
}
}
this is Example query class
class UserQueries {
static final userInsertQuery = gql(r'''
mutation Insert_users($objects: [users_insert_input!]!, $onConflict: users_on_conflict) {
insert_users(objects: $objects, on_conflict: $onConflict) {
returning {
id
name
timestamp
}
}
}
''');
}
and how to call api
Future insertUserApi(String name) async {
try {
Map<String, dynamic> variables = <String, dynamic>{};
variables = {
"objects": [
{"name": name}
],
"onConflict": {
"constraint": "users_pkey",
"update_columns": [
"id",
"name",
]
}
};
await GraphQLUtils()
.queryRepo(UserQueries.userInsertQuery, variables)
.then((response) async {
if (response["data"] != null) {
print("----Data---:${response["data"]}");
Get.back();
} else {
Get.snackbar(
"Error",
"Something Went wrong",
);
}
});
} catch (e, st) {
Get.snackbar(
"Error",
e.toString(),
);
}
}
I am passing the authentication token from Auth.dart file to Products.dart file to enable the app to fetch the Products in my database but the app is not able to fetch those,
I am very new to flutter any help would be appreciated
Thank you
here is my Auth.dart file
import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:http/http.dart' as http;
import '../models/http_exceptions.dart';
class Auth with ChangeNotifier {
String _token;
DateTime _expiryDate;
String _userId;
bool get isAuth {
return token != null;
}
String get token {
if (_expiryDate != null &&
_expiryDate.isAfter(DateTime.now()) &&
_token != null) {
return _token;
}
return null;
}
Future<void> _authenticate(
String email, String password, String urlSegment) async {
final url = Uri.parse(
'https://identitytoolkit.googleapis.com/v1/accounts:$urlSegment?key=<key>',
);
try {
final response = await http.post(
url,
body: json.encode(
{
'email': email,
'password': password,
'returnSecureToken': true,
},
),
);
final responseData = json.decode(response.body);
if (responseData['error'] != null) {
throw HttpEception(responseData['error']['message']);
}
_token = responseData['idToken'];
_userId = responseData['localId'];
_expiryDate = DateTime.now().add(
Duration(
seconds: int.parse(responseData['expiresIn']),
),
);
notifyListeners();
} catch (error) {
throw error;
}
}
Future<void> signup(String email, String password) async {
return _authenticate(email, password, 'signUp');
}
Future<void> login(String email, String password) async {
return _authenticate(email, password, 'signInWithPassword');
}
}
Here is my Products.dart file, which has the Product class which is
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shop_app/models/http_exceptions.dart';
class Product with ChangeNotifier {
final String id;
final String title;
final String description;
final double price;
final String imageUrl;
bool isFavorite;
Product({
#required this.id,
#required this.title,
#required this.description,
#required this.price,
#required this.imageUrl,
this.isFavorite = false,
});
Future<void> toggleFavoriteStatus() async {
final url = Uri.https(
'<confedential>.firebaseio.com',
'/products/$id.json',
);
final oldStatus = isFavorite;
isFavorite = !isFavorite;
notifyListeners();
final response = await http.patch(
url,
body: json.encode(
{
'isFavorite': isFavorite,
},
),
);
if (response.statusCode >= 400) {
isFavorite = oldStatus;
notifyListeners();
throw HttpEception('Could Not Change To Favourite');
}
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shop_app/models/http_exceptions.dart';
import './product.dart';
class Products with ChangeNotifier {
List<Product> _items = [];
final String authToken;
Products(this.authToken,this._items);
List<Product> get items {
return [..._items];
}
List<Product> get favoriteItems {
return _items.where((prodItem) => prodItem.isFavorite).toList();
}
Product findById(String id) {
return _items.firstWhere((prod) => prod.id == id);
}
Future<void> fetchAndSetProducts() async {
final url = Uri.https(
'<details>.firebaseio.com',
'/products.json?auth=$authToken',
);
try {
final response = await http.get(url);
// print(json.decode(response.body));
final extractedData = json.decode(response.body) as Map<String, dynamic>;
if (extractedData == null) {
return;
}
final List<Product> loadedProducts = [];
extractedData.forEach((productId, productData) {
loadedProducts.add(
Product(
id: productId,
title: productData['title'],
description: productData['description'],
price: productData['price'],
isFavorite: productData['isFavourite'],
imageUrl: productData['imageUrl'],
),
);
});
_items = loadedProducts;
notifyListeners();
} catch (error) {
throw error;
}
}
Future<void> addProduct(Product product) async {
var url = Uri.https(
'<details>.firebaseio.com',
'/products.json',
);
try {
final response = await http.post(
url,
body: json.encode(
{
'title': product.title,
'description': product.description,
'imageUrl': product.imageUrl,
'price': product.price,
'isFavourite': product.isFavorite,
},
),
);
final newProduct = Product(
title: product.title,
description: product.description,
price: product.price,
imageUrl: product.imageUrl,
id: json.decode(response.body)['name'],
);
_items.add(newProduct);
notifyListeners();
} catch (error) {
throw error;
}
}
Future<void> updateProduct(String id, Product newProduct) async {
final prodIndex = _items.indexWhere((prod) => prod.id == id);
if (prodIndex >= 0) {
final url = Uri.https(
'<details>.firebaseio.com',
'/products/$id.json',
);
http.patch(
url,
body: json.encode(
{
'title': newProduct.title,
'description': newProduct.description,
'imageUrl': newProduct.imageUrl,
'price': newProduct.price,
},
),
);
_items[prodIndex] = newProduct;
notifyListeners();
} else {
print('...');
}
}
Future<void> deleteProduct(String id) async {
final url = Uri.https(
'<details>.firebaseio.com',
'/products/$id.json',
);
final exisitingProductIndex = _items.indexWhere((prod) => prod.id == id);
var exisitingProduct = _items[exisitingProductIndex];
_items.removeAt(exisitingProductIndex);
notifyListeners();
final response = await http.delete(url);
if (response.statusCode >= 400) {
_items.insert(exisitingProductIndex, exisitingProduct);
notifyListeners();
throw HttpEception('Could Not Delete Product.');
}
exisitingProduct = null;
}
}
And finally the main.dart file which uses all this stuff
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './providers/auth.dart';
import './screens/cart_screen.dart';
import './screens/products_overview_screen.dart';
import './screens/product_detail_screen.dart';
import './providers/products.dart';
import './providers/cart.dart';
import './providers/orders.dart';
import './screens/orders_screen.dart';
import './screens/user_products_screen.dart';
import './screens/edit_product_screen.dart';
import './screens/auth_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
// Defining these providers for lisening to changes in the data
providers: [
ChangeNotifierProvider.value(
value: Auth(),
),
// First parameter is the type of data that we depened on and second is the data that we arre passing
ChangeNotifierProxyProvider<Auth, Products>(
update: (ctx, auth, previousProducts) => Products(
auth.token,
previousProducts == null ? [] : previousProducts.items,
),
),
ChangeNotifierProvider.value(
value: Cart(),
),
ChangeNotifierProvider.value(
value: Orders(),
),
],
child: Consumer<Auth>(
builder: (context, auth, _) => MaterialApp(
title: 'MyShop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
// home: ProductsOverviewScreen(),
home: auth.isAuth ? ProductsOverviewScreen() : AuthScreen(),
routes: {
ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
CartScreen.routeName: (ctx) => CartScreen(),
OrdersScreen.routeName: (ctx) => OrdersScreen(),
UserProductsScreen.routeName: (ctx) => UserProductsScreen(),
EditProductScreen.routeName: (ctx) => EditProductScreen(),
},
),
),
);
}
}
Just added create into ChangeNotifierProxyProvider
ChangeNotifierProxyProvider<Auth, Products>(
create: (_)=>Products('',[]),
update: (ctx, auth, previousProducts) => Products(
auth.token,
previousProducts == null ? [] : previousProducts.items,
),
),
and changed the url string in Products.dart file
Uri url = Uri.parse(
'https://<some_details>.firebaseio.com/products.json?auth=$authToken');
I am trying to show the JSON data from a URL to my Flutter application and haven't found any solution yet. because i have the error:
[LateInitializationError: Field '_userData#577066488' has not been initialized]
How to show this data in the ListView in Flutter?
Here is My Complete Project Flutter:
The Url Parse:
http://jsonplaceholder.typicode.com/users
Main.dart
import 'package:flutter/material.dart';
import 'json_parse_demo.dart';
void main() {
runApp(const HomeApp());
}
class HomeApp extends StatelessWidget {
const HomeApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: JsonParseDemo(),
);
}
}
users.dart
// To parse this JSON data, do
//
// final users = usersFromJson(jsonString);
// ignore_for_file: file_names
import 'dart:convert';
User userFromJson(String str) => User.fromJson(json.decode(str));
String userToJson(User data) => json.encode(data.toJson());
class User {
User({
required this.user,
});
List<UserElement> user;
factory User.fromJson(Map<String, dynamic> json) => User(
user: List<UserElement>.from(
json["User"].map((x) => UserElement.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"User": List<dynamic>.from(user.map((x) => x.toJson())),
};
}
class UserElement {
UserElement({
required this.id,
required this.name,
required this.username,
required this.email,
required this.address,
required this.phone,
required this.website,
required this.company,
});
int id;
String name;
String username;
String email;
Address address;
String phone;
String website;
Company company;
factory UserElement.fromJson(Map<String, dynamic> json) => UserElement(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address.toJson(),
"phone": phone,
"website": website,
"company": company.toJson(),
};
}
class Address {
Address({
required this.street,
required this.suite,
required this.city,
required this.zipcode,
required this.geo,
});
String street;
String suite;
String city;
String zipcode;
Geo geo;
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo.toJson(),
};
}
class Geo {
Geo({
required this.lat,
required this.lng,
});
String lat;
String lng;
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
Company({
required this.name,
required this.catchPhrase,
required this.bs,
});
String name;
String catchPhrase;
String bs;
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
servicios.dart
import 'package:http/http.dart' as http;
import 'users.dart';
class Services {
//
static Uri uri = Uri.parse('http://jsonplaceholder.typicode.com/users');
static Future<List<User>> getUsers() async {
try {
final response = await http.get(uri);
if (200 == response.statusCode) {
final List<User> users = userFromJson(response.body) as List<User>;
return users;
} else {
return <User>[];
}
} catch (e) {
return <User>[];
}
}
}
json_parse_demo.dart
// ignore_for_file: unnecessary_null_comparison
import 'package:flutter/material.dart';
import 'users.dart';
import 'servicios.dart';
class JsonParseDemo extends StatefulWidget {
//
const JsonParseDemo({Key? key}) : super(key: key);
#override
_JsonParseDemoState createState() => _JsonParseDemoState();
}
class _JsonParseDemoState extends State<JsonParseDemo> {
//
late List<User> _users;
// late bool _loading;
bool _loading = true;
#override
void initState() {
super.initState();
_loading = true;
Services.getUsers().then((users) {
setState(() {
_users = users;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Users'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: null == _users ? 0 : _users.length,
itemBuilder: (context, index) {
UserElement user = _users[index] as UserElement;
return ListTile(
title: Text(user.name),
subtitle: Text(user.email),
);
},
),
),
);
}
}
Make a function of future with async return then call it function in initstate (){}.
Because getUser api call is a asynchronous task.
Change your code like this.
#override
void initState() {
super.initState();
_loading = true;
getUserApiCall ();
}
Future getUserApiCall() async{
return await Services.getUsers().then((users) {
setState(() {
_users = users;
_loading = false;
});
});
}
If you facing any issues let me know
I am learning flutter and trying to parse a JSON just like in this article, but getting this error.
lib/service/apiservice.dart:11:33: Error: A value of type 'Data' can't
be assigned to a variable of type 'List'.
- 'Data' is from 'package:gocorona/models/totals.dart' ('lib/models/totals.dart').
- 'List' is from 'dart:core'.
final List data = dataFromJson(response.body);
lib/service/apiservice.dart
import 'package:http/http.dart' as http;
import 'package:gocorona/models/totals.dart';
class ApiServices {
static const String url = 'https://api.rootnet.in/covid19-in/stats/latest';
static Future<List<Data>> getDataFromAPI() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final List<Data> data = dataFromJson(response.body);
return data;
} else {
return List<Data>();
}
} catch (e) {
return List<Data>();
}
}
}
lib/models/totals.dart
import 'dart:convert';
Data dataFromJson(String str) => Data.fromJson(json.decode(str));
String dataToJson(Data data) => json.encode(data.toJson());
class Data {
bool success;
DataClass data;
DateTime lastRefreshed;
DateTime lastOriginUpdate;
Data({
this.success,
this.data,
this.lastRefreshed,
this.lastOriginUpdate,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
success: json["success"],
data: DataClass.fromJson(json["data"]),
lastRefreshed: DateTime.parse(json["lastRefreshed"]),
lastOriginUpdate: DateTime.parse(json["lastOriginUpdate"]),
);
Map<String, dynamic> toJson() => {
"success": success,
"data": data.toJson(),
"lastRefreshed": lastRefreshed.toIso8601String(),
"lastOriginUpdate": lastOriginUpdate.toIso8601String(),
};
}
class DataClass {
Summary summary;
List<UnofficialSummary> unofficialSummary;
List<Regional> regional;
DataClass({
this.summary,
this.unofficialSummary,
this.regional,
});
factory DataClass.fromJson(Map<String, dynamic> json) => DataClass(
summary: Summary.fromJson(json["summary"]),
unofficialSummary: List<UnofficialSummary>.from(json["unofficial-summary"].map((x) => UnofficialSummary.fromJson(x))),
regional: List<Regional>.from(json["regional"].map((x) => Regional.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"summary": summary.toJson(),
"unofficial-summary": List<dynamic>.from(unofficialSummary.map((x) => x.toJson())),
"regional": List<dynamic>.from(regional.map((x) => x.toJson())),
};
}
class Regional {
String loc;
int confirmedCasesIndian;
int discharged;
int deaths;
int confirmedCasesForeign;
int totalConfirmed;
Regional({
this.loc,
this.confirmedCasesIndian,
this.discharged,
this.deaths,
this.confirmedCasesForeign,
this.totalConfirmed,
});
factory Regional.fromJson(Map<String, dynamic> json) => Regional(
loc: json["loc"],
confirmedCasesIndian: json["confirmedCasesIndian"],
discharged: json["discharged"],
deaths: json["deaths"],
confirmedCasesForeign: json["confirmedCasesForeign"],
totalConfirmed: json["totalConfirmed"],
);
Map<String, dynamic> toJson() => {
"loc": loc,
"confirmedCasesIndian": confirmedCasesIndian,
"discharged": discharged,
"deaths": deaths,
"confirmedCasesForeign": confirmedCasesForeign,
"totalConfirmed": totalConfirmed,
};
}
class Summary {
int total;
int confirmedCasesIndian;
int confirmedCasesForeign;
int discharged;
int deaths;
int confirmedButLocationUnidentified;
Summary({
this.total,
this.confirmedCasesIndian,
this.confirmedCasesForeign,
this.discharged,
this.deaths,
this.confirmedButLocationUnidentified,
});
factory Summary.fromJson(Map<String, dynamic> json) => Summary(
total: json["total"],
confirmedCasesIndian: json["confirmedCasesIndian"],
confirmedCasesForeign: json["confirmedCasesForeign"],
discharged: json["discharged"],
deaths: json["deaths"],
confirmedButLocationUnidentified: json["confirmedButLocationUnidentified"],
);
Map<String, dynamic> toJson() => {
"total": total,
"confirmedCasesIndian": confirmedCasesIndian,
"confirmedCasesForeign": confirmedCasesForeign,
"discharged": discharged,
"deaths": deaths,
"confirmedButLocationUnidentified": confirmedButLocationUnidentified,
};
}
class UnofficialSummary {
String source;
int total;
int recovered;
int deaths;
int active;
UnofficialSummary({
this.source,
this.total,
this.recovered,
this.deaths,
this.active,
});
factory UnofficialSummary.fromJson(Map<String, dynamic> json) => UnofficialSummary(
source: json["source"],
total: json["total"],
recovered: json["recovered"],
deaths: json["deaths"],
active: json["active"],
);
Map<String, dynamic> toJson() => {
"source": source,
"total": total,
"recovered": recovered,
"deaths": deaths,
"active": active,
};
}
lib/screens/states.dart
import 'package:flutter/material.dart';
import 'package:gocorona/models/totals.dart';
import 'package:gocorona/service/apiservice.dart';
class Statewise extends StatefulWidget {
#override
_StatewiseState createState() => _StatewiseState();
}
class _StatewiseState extends State<Statewise> {
List<Data> _datafromApi;
bool _isloading;
#override
void initState() {
super.initState();
_isloading = true;
ApiServices.getDataFromAPI().then((data) {
setState(() {
_datafromApi = data;
_isloading = false;
});
});
}
#override
Widget build(BuildContext context) {
if (_isloading) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return Scaffold(
body: ListView.builder(
itemCount: _datafromApi == null ? 0 : _datafromApi.length,
itemBuilder: (context, index) {
Data datas = _datafromApi[index];
print(datas?.toString() ?? "Empty");
return ListTile(
title: Text(
datas.data.regional[0].loc.toString(),
style: TextStyle(color: Colors.black),
));
}),
);
}
}
}
Compiler message:
lib/service/apiservice.dart:11:33: Error: A value of type 'Data' can't be assigned to a variable of type 'List<Data>'.
- 'Data' is from 'package:gocorona/models/totals.dart' ('lib/models/totals.dart').
- 'List' is from 'dart:core'.
final List<Data> data = dataFromJson(response.body);
^
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.17.0, on Microsoft Windows [Version 10.0.18362.778], locale en-IN)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[√] Android Studio (version 3.6)
[√] VS Code (version 1.45.0)
[√] Connected device (1 available)
• No issues found!
This was happening because you was returning only data from constructor and you was trying to accept it as a List.
I made a few changes i hope it will help you.
class ApiServices {
static const String url = 'https://api.rootnet.in/covid19-in/stats/latest';
static Future<Data> getDataFromAPI() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
print(response.toString());
final data = dataFromJson(response.body);
// print(data);
return data;
} else {
return Data();
}
} catch (e) {
return Data();
}
}
}
Data dataFromJson(String str) => Data.fromJson(json.decode(str));
String dataToJson(Data data) => json.encode(data.toJson());
class Data {
bool success;
DataClass data;
DateTime lastRefreshed;
DateTime lastOriginUpdate;
Data({
this.success,
this.data,
this.lastRefreshed,
this.lastOriginUpdate,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
success: json["success"],
data: DataClass.fromJson(json["data"]),
lastRefreshed: DateTime.parse(json["lastRefreshed"]),
lastOriginUpdate: DateTime.parse(json["lastOriginUpdate"]),
);
Map<String, dynamic> toJson() => {
"success": success,
"data": data.toJson(),
"lastRefreshed": lastRefreshed.toIso8601String(),
"lastOriginUpdate": lastOriginUpdate.toIso8601String(),
};
}
class DataClass {
Summary summary;
List<UnofficialSummary> unofficialSummary;
List<Regional> regional;
DataClass({
this.summary,
this.unofficialSummary,
this.regional,
});
factory DataClass.fromJson(Map<String, dynamic> json) => DataClass(
summary: Summary.fromJson(json["summary"]),
unofficialSummary: List<UnofficialSummary>.from(
json["unofficial-summary"]
.map((x) => UnofficialSummary.fromJson(x))),
regional: List<Regional>.from(
json["regional"].map((x) => Regional.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"summary": summary.toJson(),
"unofficial-summary":
List<dynamic>.from(unofficialSummary.map((x) => x.toJson())),
"regional": List<dynamic>.from(regional.map((x) => x.toJson())),
};
}
class Regional {
String loc;
int confirmedCasesIndian;
int discharged;
int deaths;
int confirmedCasesForeign;
int totalConfirmed;
Regional({
this.loc,
this.confirmedCasesIndian,
this.discharged,
this.deaths,
this.confirmedCasesForeign,
this.totalConfirmed,
});
factory Regional.fromJson(Map<String, dynamic> json) => Regional(
loc: json["loc"],
confirmedCasesIndian: json["confirmedCasesIndian"],
discharged: json["discharged"],
deaths: json["deaths"],
confirmedCasesForeign: json["confirmedCasesForeign"],
totalConfirmed: json["totalConfirmed"],
);
Map<String, dynamic> toJson() => {
"loc": loc,
"confirmedCasesIndian": confirmedCasesIndian,
"discharged": discharged,
"deaths": deaths,
"confirmedCasesForeign": confirmedCasesForeign,
"totalConfirmed": totalConfirmed,
};
}
class Summary {
int total;
int confirmedCasesIndian;
int confirmedCasesForeign;
int discharged;
int deaths;
int confirmedButLocationUnidentified;
Summary({
this.total,
this.confirmedCasesIndian,
this.confirmedCasesForeign,
this.discharged,
this.deaths,
this.confirmedButLocationUnidentified,
});
factory Summary.fromJson(Map<String, dynamic> json) => Summary(
total: json["total"],
confirmedCasesIndian: json["confirmedCasesIndian"],
confirmedCasesForeign: json["confirmedCasesForeign"],
discharged: json["discharged"],
deaths: json["deaths"],
confirmedButLocationUnidentified:
json["confirmedButLocationUnidentified"],
);
Map<String, dynamic> toJson() => {
"total": total,
"confirmedCasesIndian": confirmedCasesIndian,
"confirmedCasesForeign": confirmedCasesForeign,
"discharged": discharged,
"deaths": deaths,
"confirmedButLocationUnidentified": confirmedButLocationUnidentified,
};
}
class UnofficialSummary {
String source;
int total;
int recovered;
int deaths;
int active;
UnofficialSummary({
this.source,
this.total,
this.recovered,
this.deaths,
this.active,
});
factory UnofficialSummary.fromJson(Map<String, dynamic> json) =>
UnofficialSummary(
source: json["source"],
total: json["total"],
recovered: json["recovered"],
deaths: json["deaths"],
active: json["active"],
);
Map<String, dynamic> toJson() => {
"source": source,
"total": total,
"recovered": recovered,
"deaths": deaths,
"active": active,
};
}
class Statewise extends StatefulWidget {
#override
_StatewiseState createState() => _StatewiseState();
}
class _StatewiseState extends State<Statewise> {
Data _datafromApi;
bool _isloading;
#override
void initState() {
super.initState();
_isloading = true;
ApiServices.getDataFromAPI().then((data) {
setState(() {
_datafromApi = data;
_isloading = false;
});
});
}
#override
Widget build(BuildContext context) {
if (_isloading) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return Scaffold(
body: ListView.builder(
itemCount:
_datafromApi == null ? 0 : _datafromApi.data.regional.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
_datafromApi.data.regional[index].loc.toString(),
style: TextStyle(color: Colors.black),
));
}),
);
}
}
}
What you are doing is
List<Data> data = Data();
//trying to assign a Data to List of Data: List<Data>
//which is very similar to
List<String> aString = String();
//String should be treated as String but you are treating it as List<String>
This will work
Data data = Data()
//in your case
Data data = dataFromJson();
Initially when you hit the api you get a response as a complete single object
var data = dataFromJson(response.body);
the above data is the single object and not list of objects List
So may initially you get the complete object. i have made an example below based on your written example.
Model class based on the json data
// To parse this JSON data, do
//
// final data = dataFromJson(jsonString);
import 'dart:convert';
Data dataFromJson(String str) => Data.fromJson(json.decode(str));
String dataToJson(Data data) => json.encode(data.toJson());
class Data {
bool success;
DataClass data;
DateTime lastRefreshed;
DateTime lastOriginUpdate;
Data({
this.success,
this.data,
this.lastRefreshed,
this.lastOriginUpdate,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
success: json["success"],
data: DataClass.fromJson(json["data"]),
lastRefreshed: DateTime.parse(json["lastRefreshed"]),
lastOriginUpdate: DateTime.parse(json["lastOriginUpdate"]),
);
Map<String, dynamic> toJson() => {
"success": success,
"data": data.toJson(),
"lastRefreshed": lastRefreshed.toIso8601String(),
"lastOriginUpdate": lastOriginUpdate.toIso8601String(),
};
}
class DataClass {
Summary summary;
List<UnofficialSummary> unofficialSummary;
List<Regional> regional;
DataClass({
this.summary,
this.unofficialSummary,
this.regional,
});
factory DataClass.fromJson(Map<String, dynamic> json) => DataClass(
summary: Summary.fromJson(json["summary"]),
unofficialSummary: List<UnofficialSummary>.from(json["unofficial-summary"].map((x) => UnofficialSummary.fromJson(x))),
regional: List<Regional>.from(json["regional"].map((x) => Regional.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"summary": summary.toJson(),
"unofficial-summary": List<dynamic>.from(unofficialSummary.map((x) => x.toJson())),
"regional": List<dynamic>.from(regional.map((x) => x.toJson())),
};
}
class Regional {
String loc;
int confirmedCasesIndian;
int discharged;
int deaths;
int confirmedCasesForeign;
int totalConfirmed;
Regional({
this.loc,
this.confirmedCasesIndian,
this.discharged,
this.deaths,
this.confirmedCasesForeign,
this.totalConfirmed,
});
factory Regional.fromJson(Map<String, dynamic> json) => Regional(
loc: json["loc"],
confirmedCasesIndian: json["confirmedCasesIndian"],
discharged: json["discharged"],
deaths: json["deaths"],
confirmedCasesForeign: json["confirmedCasesForeign"],
totalConfirmed: json["totalConfirmed"],
);
Map<String, dynamic> toJson() => {
"loc": loc,
"confirmedCasesIndian": confirmedCasesIndian,
"discharged": discharged,
"deaths": deaths,
"confirmedCasesForeign": confirmedCasesForeign,
"totalConfirmed": totalConfirmed,
};
}
class Summary {
int total;
int confirmedCasesIndian;
int confirmedCasesForeign;
int discharged;
int deaths;
int confirmedButLocationUnidentified;
Summary({
this.total,
this.confirmedCasesIndian,
this.confirmedCasesForeign,
this.discharged,
this.deaths,
this.confirmedButLocationUnidentified,
});
factory Summary.fromJson(Map<String, dynamic> json) => Summary(
total: json["total"],
confirmedCasesIndian: json["confirmedCasesIndian"],
confirmedCasesForeign: json["confirmedCasesForeign"],
discharged: json["discharged"],
deaths: json["deaths"],
confirmedButLocationUnidentified: json["confirmedButLocationUnidentified"],
);
Map<String, dynamic> toJson() => {
"total": total,
"confirmedCasesIndian": confirmedCasesIndian,
"confirmedCasesForeign": confirmedCasesForeign,
"discharged": discharged,
"deaths": deaths,
"confirmedButLocationUnidentified": confirmedButLocationUnidentified,
};
}
class UnofficialSummary {
String source;
int total;
int recovered;
int deaths;
int active;
UnofficialSummary({
this.source,
this.total,
this.recovered,
this.deaths,
this.active,
});
factory UnofficialSummary.fromJson(Map<String, dynamic> json) => UnofficialSummary(
source: json["source"],
total: json["total"],
recovered: json["recovered"],
deaths: json["deaths"],
active: json["active"],
);
Map<String, dynamic> toJson() => {
"source": source,
"total": total,
"recovered": recovered,
"deaths": deaths,
"active": active,
};
}
Below is the api service call
class ApiServices {
static const String url = 'https://api.rootnet.in/covid19-in/stats/latest';
static Future<Data> getDataFromAPI() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final Data data = dataFromJson(response.body);
//regionalData = data.data.regional;
// And make the return value as List<Regional> or send the complete object which is benefiicial
return data;
} else {
return null;
}
} catch (e) {
return null;
}
}
}
And lastly the ui shown below :
oid main()=> runApp(Statewise());
class Statewise extends StatefulWidget {
#override
_StatewiseState createState() => _StatewiseState();
}
class _StatewiseState extends State<Statewise> {
Data responseData;
bool _isloading;
List<Regional> regionalData;
#override
void initState() {
super.initState();
_isloading = true;
ApiServices.getDataFromAPI().then((data) {
// you can initially get the regional data from the getDataFromAPI() method
setState(() {
responseData = data;// here you get the complete object
// here you can also get the regional data only from below code
//regionalData = data.data.regional; and assign to the List<Regional>
_isloading = false;
});
});
}
#override
Widget build(BuildContext context) {
if (_isloading) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return MaterialApp(
home: Scaffold(
body: ListView.builder(
itemCount: responseData.data.regional == null ? 0 : responseData.data.regional.length,
itemBuilder: (context, index) {
var region = responseData.data.regional[index];
//Data datas = _datafromApi[index];
//print(datas?.toString() ?? "Empty");
return ListTile(
title: Text(
region.loc.toString(),
style: TextStyle(color: Colors.black),
));
}),
),
);
}
}
}
Check out and let me know if you have problem.