Cant get length in listview.builder in Flutter - flutter

I'm learning flutter and dart language and trying to apply bloc pattern by rxdart and show data in the page.
Can't get length or display a data in page stream builder and listview.builder because I receive error:
class 'Future<List<User>>' has no instance getter 'length'.
Receiver: Instance of 'Future<List<User>>'
Tried calling: length
My class user.dart
class User {
int id;
String name;
String username;
String email;
User({this.id, this.name, this.username, this.email});
User.fromJson(Map<String, dynamic> parsedJson) {
User(
id: parsedJson['id'],
name: parsedJson['name'],
username: parsedJson['username'],
email: parsedJson['email'],
);
}
}
// user_repo.dart
import 'package:learn_flutter_bloc/bloc_rx_example/User.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import 'package:learn_flutter_bloc/url.dart';
class UserRepo {
static Future<List<User>> getUsers() async {
final res = await http.get("https://jsonplaceholder.typicode.com/users");
List<User> users = [];
if (res.statusCode == 200) {
var data = jsonDecode(res.body);
for (var user in data) {
users.add(User.fromJson(user));
}
return users;
} else {
throw Exception("Error In Calling APi");
}
}
}
// user_bloc
import 'package:learn_flutter_bloc/bloc_base.dart';
import 'package:learn_flutter_bloc/bloc_rx_example/user_repo.dart';
import 'package:rxdart/subjects.dart';
class UserBloc extends BlocBase {
Subject _usersSubject = BehaviorSubject();
Stream get users => _usersSubject.stream;
getUsers() async {
var usersData = UserRepo.getUsers();
_usersSubject.add(usersData);
}
#override
dispose() {
_usersSubject.close();
}
}
final bloc = UserBloc();
// user_list_app.dart
import 'package:flutter/material.dart';
import 'package:learn_flutter_bloc/bloc_rx_example/user_bloc.dart';
class UserListApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Bloc Rx Example',
theme: ThemeData(
primaryColor: Colors.teal,
),
home: Scaffold(
appBar: AppBar(
title: Text('Bloc Rx Example'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop();
}),
),
body: UserList(),
),
);
}
}
class UserList extends StatefulWidget {
#override
_UserListState createState() => _UserListState();
}
class _UserListState extends State<UserList> {
#override
void dispose() {
bloc.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
bloc.getUsers();
return Padding(
padding: EdgeInsets.all(10.0),
child: StreamBuilder(
stream: bloc.users,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.weekend),
title: Text('${snapshot.data[index].name}'),
);
});
} else if (!snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}

While you are using StreamBuilder in the UI, Your getUsers() is returning Future<List<User>> . Return Stream<<List<User>> from getUsers() .

Fixed I problem was in bloc_user.dart misssing await
Future<List<User>> getUsers() async {
var usersData = UserRepo.getUsers();
print(usersData);
_usersSubject.sink.add(usersData);
}
to
Future<List<User>> getUsers() async {
var usersData = await UserRepo.getUsers();
print(usersData);
_usersSubject.sink.add(usersData);
}

Related

flutter does not show data from API

When I try to pull data from the jsonplaceholder API and put it on the screen, I don't have any problems, but when I try to change the data in this link (https://reqres.in/api/users?page=2 ) on the reqres.io site with the same codes, only by changing the API and model, the text no data appears on the screen. I'm getting it can you help me ?
My project with JsonPlaceHolder
main.dart
import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() =\> runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State\<Home\> createState() =\> \_HomeState();
}
class \_HomeState extends State\<Home\> {
List\<JsonModel\>? \_postItems;
bool \_isLoading = false;
String? \_errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future\<void\> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (\_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (\_postItems == null || \_postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: \_postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(\_postItems!\[index\].name),
);
},
);
}
}
}`
api_service.dart
`import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<JsonModel>?> fetchApi() async {
final res = await Dio().get("https://jsonplaceholder.typicode.com/users");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!;
if (data is List) {
return data.map((e) =\> JsonModel.fromMap(e)).toList();
}
}
return <JsonModel>[];
}
}
`
conclusion
conclusion
My project with reqres.in
main.dart
`import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() =\> runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<ReqresModel>? _postItems;
bool _isLoading = false;
String? _errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (_postItems == null || _postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: _postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(\_postItems!\[index\].data\[index\].firstName),
);
},
);
}
}
}`
api_servise.dart
`import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<ReqresModel>?> fetchApi() async {
final res = await Dio().get("https://reqres.in/api/users?page=2");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!;
if (data is List) {
return data.map((e) => ReqresModel.fromMap(e)).toList();
}
}
return <ReqresModel>[];
}
}`
conclusion
conclusion
**Thank you **
I sent the API using Postman, there was no problem, I don't think the problem was caused by the API, sorry for my bad English
Change your api_service.dart for reqres.in project with following code.
First api which returns List directly, but second api which return Json which has data as List
Edited
main.dart
import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<ReqresModel>? _postItems;
bool _isLoading = false;
String? _errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (_postItems == null || _postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: _postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_postItems![index].firstName),//Updated here
);
},
);
}
}
}
api_service.dart
import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<ReqresModel>?> fetchApi() async {
final res = await Dio().get("https://reqres.in/api/users?page=2");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!['data'];//Updated here
if (data is List) {
return data.map((e) => ReqresModel.fromMap(e)).toList();
}
}
return <ReqresModel>[];
}
}
ReqresModel - should be updated
//Updated here
class ReqresModel {
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
ReqresModel(
{this.id, this.email, this.firstName, this.lastName, this.avatar});
ReqresModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
}

NoSuchMethodError: 'cast' with dart language

i'm following flutter offical docs to parse JSON in the background with the rest api from themoviedb. I get this following error when trying to show the list of movies
the api link : https://api.themoviedb.org/3/trending/movie/week?api_key=$apiKey
json data
app.dart'
simplify main.dart and isolate parsing using compute
import 'dart:convert';
import 'package:flutter/material.dart';
import 'models/movie_response.dart';
import 'package:auth_request/api_key.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
Future<List<Movie>> fetchMovies(http.Client client) async {
final response = await client
.get(Uri.parse('https://api.themoviedb.org/3/trending/movie/week?api_key=$apiKey'));
// Use the compute funtion to run fetchMovies in a separate isolate
return compute(parseMovies, response.body);
}
// A function that converts a response body into a List<Movie>.
List<Movie> parseMovies(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Movie>((json) => Movie.fromJson(json)).toList();
}
class MovieApp extends StatefulWidget {
const MovieApp({super.key});
#override
MovieAppState createState() => MovieAppState();
}
class MovieAppState extends State<MovieApp> {
late Future<Movie> futureAlbum;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MovieDB List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('MovieDB List'),
),
body: Center(
child: FutureBuilder<List<Movie>>(
future: fetchMovies(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('${snapshot.error}');
} else if (snapshot.hasData) {
return MoviesList(movies: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
),
);
}
}
//
class MoviesList extends StatelessWidget {
const MoviesList({super.key, required this.movies});
final List<Movie> movies;
#override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemBuilder: (context, index) {
return Image.network(movies[index].original_title);
},
);
}
}
movie.dart
Parse and convert the JSON into a list of movies with the help of map and factory
class Movie {
final String original_title;
final String overview;
final String poster_path;
final String release_date;
const Movie({
required this.original_title,
required this.overview,
required this.poster_path,
required this.release_date,
});
factory Movie.fromJson(Map<String, dynamic> json) {
return Movie(
original_title: json['original_title'],
overview: json['overview'],
poster_path: json['poster_path'],
release_date: json['release_date'],
);
}
}
change this:
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
to
final parsed = jsonDecode(responseBody)['results'];

Flutter: Stream data from rest api using Cubit

The idea is to fetch data from api continuously and show this data in screen, without need to fetch manually, like that if someone else perform a change on server data this change will be shown without user refreshing action.
The implementation is done in Flutter BLoC (cubit).
I have already get a console print of data in the cubit but I can't get same data in the BlocBuilder neither in the BlocListener.
My code is:
//data_repository.dart
import 'dart:async';
import 'data.dart';
class DataRepository {
final DataApi dataApi;
List<Map<String, dynamic>> formatedData = [];
final _controller = StreamController<List<Map<String, dynamic>>>();
DataRepository(this.dataApi) {
getData();
}
Future<void> getData() async {
Timer.periodic(Duration(seconds: 5), (timer) async {
formatedData.clear();
Map<String, dynamic> res = await dataApi.getData();
List<dynamic> data = res['data'];
for (var el in data) {
formatedData.add({'id': el['id'], 'name': el['name']});
}
_controller.add(formatedData);
});
}
#override
Stream<List<Map<String, dynamic>>> data() async* {
yield* _controller.stream;
}
#override
void dispose() => _controller.close();
}
Blockquote
This code is Data Repository it get data and make it available via a StreamController named "_controller";
Here data is got and controller is working perfectly.
My Cubit State is like this:
//data_list_state.dart
class DataListState extends Equatable {
final List<Map<String, dynamic>> data;
DataListState(this.data);
#override
List<Object> get props => [data];
DataListState copyWith({
List<Map<String, dynamic>>? data,
}) {
return DataListState(
data ?? this.data,
);
}
}
When I print within copyWith() I get updated data;
My Cubit code:
//data_list_cubit.dart
class DataListCubit extends Cubit<DataListState> {
DataListCubit(this.dataRepository) : super(DataListState([])) {
loadList();
}
final DataRepository dataRepository;
loadList() {
dataRepository.data().listen((event) {
if (event.isNotEmpty) {
emit(state.copyWith(data: dataRepository.formatedData));
}
});
}
}
When I print in loadList() I get the updated data;
My Screen Code:
//home.dart
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(children: [
BlocListener<DataListCubit, DataListState>(
listener: (context, state) {
if (state.data.isNotEmpty) print(state.data[0].toString());
},
child: BlocBuilder<DataListCubit, DataListState>(
builder: (context, state) {
if (state.data.isNotEmpty) print(state.data[0].toString());
return ListView(
shrinkWrap: true,
children: [
for (Map<String, dynamic> ff in state.data)
ListTile(
title: Text(ff['name']),
leading: Text(ff['id'].toString()),
),
],
);
},
),
),
]),
);
}
}
When I console print here I don't get data just for the first time, and after every 5 secondes (described in my getData()) I get updated data in all my codes excepting in the home.
Can you tell me if my cubit implementation is right ?
What should I do to make it work ?
Thanks in advance
You must add the BlocProvider above the BlocListener or BlocBuilder in HomePage.
tip: Learn BlocListener vs BlocBuilder vs BlocConsumer. All three must be enclosed in BlocProvider to work
class MyHomePage extends StatelessWidget {
DataRepository dataRepository = DataRepository();
#override
Widget build(BuildContext context) {
return SafeArea(
child: BlocProvider<DataListCubit>(
create: (context) => DataListCubit(dataRepository),
child: Scaffold(
body: BlocBuilder<DataListCubit, DataListState>(
builder: (context, state) {
print(state.data);
if (state.data.isNotEmpty) {
return ListView(
shrinkWrap: true,
children: [
for (Map<String, dynamic> ff in state.data)
ListTile(
title: Text(ff['name']),
leading: Text(ff['id'].toString()),
),
],
);
} else {
return const Center(
child: Text('No Data'),
);
}
},
),
),
),
);
}
}
Your Cubit State should be like below as you don't require
Equitable for state management in Cubit implementation
class DataListState {
const DataListState(this.data);
final List<Map<String, dynamic>> data;
DataListState copyWith({
List<Map<String, dynamic>>? data,
}) {
return DataListState(
data ?? this.data,
);
}
}
Full code
In absence of DataApi, I have structured the whole working code with random data as in below :
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Demo',
theme: ThemeData(),
home: MyHomePage(),
// home: VibrateHomepage(),
);
}
}
class MyHomePage extends StatelessWidget {
DataRepository dataRepository = DataRepository();
#override
Widget build(BuildContext context) {
return SafeArea(
child: BlocProvider<DataListCubit>(
create: (context) => DataListCubit(dataRepository),
child: Scaffold(
body: BlocBuilder<DataListCubit, DataListState>(
builder: (context, state) {
print(state.data);
if (state.data.isNotEmpty) {
return ListView(
shrinkWrap: true,
children: [
for (Map<String, dynamic> ff in state.data)
ListTile(
title: Text(ff['name']),
leading: Text(ff['id'].toString()),
),
],
);
} else {
return const Center(
child: Text('No Data'),
);
}
},
),
),
),
);
}
}
class DataRepository {
DataRepository() {
getData();
}
DataApi dataApi = DataApi();
List<Map<String, dynamic>> formattedData = [];
final _controller = StreamController<List<Map<String, dynamic>>>();
Future<void> getData() async {
Timer.periodic(const Duration(seconds: 5), (timer) async {
Map<String, dynamic> el = dataApi.getNew();
formattedData.add({'id': el['id'], 'name': el['name']});
_controller.add(formattedData);
});
}
Stream<List<Map<String, dynamic>>> data() async* {
yield* _controller.stream;
}
void dispose() => _controller.close();
}
class DataApi {
var rng = Random();
getNew() {
var rnd = rng.nextInt(100);
return {
"id": rnd,
"name": "Person " + rnd.toString()
};
}
}
class DataListState {
const DataListState(this.data);
final List<Map<String, dynamic>> data;
DataListState copyWith({
List<Map<String, dynamic>>? data,
}) {
return DataListState(
data ?? this.data,
);
}
}
class DataListCubit extends Cubit<DataListState> {
DataListCubit(this.dataRepository) : super(DataListState([])) {
loadList();
}
final DataRepository dataRepository;
loadList() {
dataRepository.data().listen((event) {
if (event.isNotEmpty) {
emit(state.copyWith(data: dataRepository.formattedData));
}
});
}
}

Unhandled Exception: LateInitializationError: Field '_db#19320762' has not been initialized

import 'package:flutter/material.dart';
import 'package:sqlflite_demo/screens/product_list.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: ProductList(),
);
}
}
main.dart
class Product {
int? id;
String? name;
String? description;
double? unitPrice;
Product({this.name, this.description, this.unitPrice});
Product.withId({this.id, this.name, this.description, this.unitPrice});
Map<String,dynamic> toMap(){
var map = Map<String,dynamic>();
map["name"]=name;
map["description"]=description;
map["unitPrice"]=unitPrice;
if(id!=null){
map["id"]=id;
}
return map;
}
Product.fromObject(dynamic o){
this.id = int.tryParse(o["id"]);
this.name=o["name"];
this.description=o["description"];
this.unitPrice = double.tryParse(o["unitPrice"].toString());
}
}
product.dart
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import '../models/product.dart';
class DbHelper {
late Database _db;
Future<Database> get db async {
if (_db == null) {
_db = await initializeDb();
}
return _db;
}
Future<Database> initializeDb() async {
String dbPath = join(await getDatabasesPath(), "etrade.db");
var eTradeDb = await openDatabase(dbPath,version: 1, onCreate: createDb);
return eTradeDb;
}
void createDb(Database db, int version)async {
await db.execute("Create table products(id integer primary key, name text, description text, unitPrice integer)");
}
Future<List<Product>> getProducts() async{
Database db = await this.db;
var result = await db.query("products");
return List.generate(result.length, (i){
return Product.fromObject(result[i]);
});
}
Future<int> insert(Product product)async{
Database db = await this.db;
var result = await db.insert("products", product.toMap());
return result; ////////
}
Future<int> delete(int id)async{
Database db = await this.db;
var result = await db.rawDelete("delete from products where id=$id");
return result;
}
Future<int> update(Product product)async{
Database db = await this.db;
var result = await db.update("products", product.toMap(), where: "id=?",whereArgs: [product.id]);
return result;
}
}
db_Helper.dart
import 'package:flutter/material.dart';
import 'package:sqlflite_demo/data/dbHelper.dart';
import 'package:sqlflite_demo/models/product.dart';
import 'package:sqlflite_demo/screens/product_add.dart';
class ProductList extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return _ProductListState();
}
}
class _ProductListState extends State {
var dbHelper = DbHelper();
late List<Product> products;
int productCount =0;
#override
void initState() {
getProducts();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Ürün Listesi"),
),
body: buildProductList(),
floatingActionButton: FloatingActionButton(
onPressed: (){goToProductAdd();},
child: Icon(Icons.add),
tooltip: "Yeni Ürün Ekle",
),
);
}
ListView buildProductList() {
return ListView.builder(
itemCount: productCount,
itemBuilder: (BuildContext context, int position){
return Card(
color: Colors.pinkAccent,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(backgroundColor: Colors.black12, child: Text("P"),),
title: Text(products[position].name.toString()),
subtitle: Text(products[position].description.toString()),
onTap: (){},
),
);
});
}
void goToProductAdd() async{
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context)=>ProductAdd()));
if(result!=null){
if(result){
getProducts();
}
}
}
void getProducts() async{
var productsFuture = dbHelper.getProducts();
productsFuture.then((data){
this.products = data;
productCount=data.length;
});
}
}
product_list.dart
import 'package:flutter/material.dart';
import 'package:sqlflite_demo/data/dbHelper.dart';
import '../models/product.dart';
class ProductAdd extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return ProductAddState();
}
}
class ProductAddState extends State {
var dbHelper = DbHelper();
var txtName=TextEditingController();
var txtDescription=TextEditingController();
var txtUnitPrice=TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Yeni Ürün Ekle"),
),
body: Padding(
padding: EdgeInsets.all(30.0),
child: Column(
children: [
buildNameField(),buildDescriptionField(),buildUnitPriceField(),buildSaveButton()
],
),
),
);
}
buildNameField() {
return TextField(
decoration: InputDecoration(labelText: "Ürün Adı"),
controller: txtName,
);
}
buildDescriptionField() {
return TextField(
decoration: InputDecoration(labelText: "Ürün Açıklaması"),
controller: txtDescription,
);
}
buildUnitPriceField() {
return TextField(
decoration: InputDecoration(labelText: "Birim Fiyatı"),
controller: txtUnitPrice,
);
}
buildSaveButton() {
return FlatButton(
child: Text("Ekle"),
onPressed: (){
addProduct();
},
);
}
void addProduct() async{
var result = await dbHelper.insert(Product(name: txtName.text, description: txtDescription.text, unitPrice: double.tryParse(txtUnitPrice.text)));
Navigator.pop(context,true);
}
}
product_add.dart
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: LateInitializationError: Field '_db#19320762' has not been initialized.
This is my first project in flutter. and I have an error. can you explain that? Thanks. I dont know what happened

I want to Show Complex JSON Data in Flutter But Getting Nothing

I am trying to show the JSON data from a URL to my Flutter application and haven't found any solution yet.
How to show this data in the ListView in Flutter?
Here is my complete Flutter project code:
Main.dart
import 'package:flutter/material.dart';
import 'package:jsontest/Json.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Cricket',
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: new JsonParseDemo(),
);
}
}
Match.dart Where Json Data is in organized form
import 'dart: convert';
Match matchesFromJson(String str) => Match.fromJson(json.decode(str));
String matchesToJson(Match data) => json.encode(data.toJson());
class Match {
Match({
this.name,
this.status,
});
String name;
String status;
factory Match.fromJson(Map<String, dynamic> json) => Match(
name: json["name"],
status: json["status"],
);
Map<String, dynamic> toJson() => {
"name": name,
"status": status,
};
}
Service.dart Here is the base URL to get JSON data
import 'package:http/http.dart' as http;
import 'Users.dart';
class Services {
//
static const String url = 'https://api.cricket.com.au/matches';
static Future<List<Match>> getMatches() async{
try{
final response = await http.get(url);
if (200 == response.statusCode){
final List<Match> match = matchesFromJson(response.body) as List<Match>;
return match;
}
else{
return List<Match>();
}
}
catch(e){
return List<Match>();
}
}
}
And here is the code of my main class where I want to show the data.
JsonParser.dart
import 'package:flutter/material.dart';
import 'Services.dart';
import 'Users.dart';
class JsonParseDemo extends StatefulWidget {
//
JsonParseDemo() : super();
#override
_JsonParseDemoState createState() => _JsonParseDemoState();
}
class _JsonParseDemoState extends State<JsonParseDemo> {
//
List<Match> _match;
bool _loading;
#override
void initState() {
super.initState();
_loading = true;
Services.getMatches().then((matches) {
setState(() {
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Matches'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: null == _match ? 0 : _match.length,
itemBuilder: (context, index) {
Match match = _match[index];
return ListTile(
title: Text(match.name),
subtitle: Text(match.status),
);
},
),
),
);
}
}
How to get "Name and Status" of the match from this JSON?
Try my code below :
json_parse_demo_screen.dart
class JsonParseDemo extends StatefulWidget {
//
JsonParseDemo() : super();
#override
_JsonParseDemoState createState() => _JsonParseDemoState();
}
class _JsonParseDemoState extends State<JsonParseDemo> {
//
List<Match> _match;
bool _loading = true;
#override
void initState() {
super.initState();
_loading = true;
Services.getMatches().then((matches) {
setState(() {
_match = matches;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Matches'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: null == _match ? 0 : _match.length,
itemBuilder: (context, index) {
Match match = _match[index];
return ListTile(
title: Text(match.name),
subtitle: Text(match.status),
);
},
),
),
);
}
}
match.dart
import 'dart:convert';
String matchesToJson(Match data) => json.encode(data.toJson());
class Match {
Match({
this.name,
this.status,
});
String name;
String status;
factory Match.fromJson(Map<String, dynamic> json) => Match(
name: json["name"],
status: json["status"],
);
Map<String, dynamic> toJson() => {
"name": name,
"status": status,
};
}
service.dart
Here, you will have to check the hierarchy of the response you get.
The hierarchy of response is:
- meta
- matchList
- matches
Then you have to look for the result you expect (here matches)
class Services {
//
static const String url = 'https://api.cricket.com.au/matches';
static Future<List<Match>> getMatches() async{
try{
final response = await http.get(url);
final responseFormatted = json.decode(response.body);
final matches = responseFormatted["matchList"]["matches"];
if (200 == response.statusCode){
final List<Match> match = matches.map<Match>((item) => Match.fromJson(item)).toList();
return match;
}
else{
return List<Match>();
}
}
catch(e){
return List<Match>();
}
}
}
Output
You didn't initialize match
List<Match> _match;
You can do it like this
Services.getMatches().then((matches) {
setState(() {
_match=matches
_loading = false;
});
});