Arguments error while trying to load a widget - android

I'm configuring sqflite into my app so that I can be able to perform crud operations. I've been working on this for days.
Everything seems fine but when I try to load a widget in routes so that I can try to experiment crud operations I keep getting errors relating to arguments when calling a widget class.
This may be a simple problem but because I'm new to flutter and dart I failing to figure this out.
Below is the main.dart file.
import 'package:flutter/material.dart';
import 'home.dart';
import 'package:com.example.simple_app/pages/create_account/create_account_page.dart';
import 'package:com.example.simple_app/pages/add_person/add_person.dart';
import 'package:com.example.simple_app/models/user.dart';
void main() => runApp(SimpleApp());
final routes = {
'/': (BuildContext context) => new CreateAccountPage(),
class SimpleApp extends StatefulWidget {
#override
_SimpleAppState createState() => _SimpleAppState();
}
class _SimpleAppState extends State<SimpleApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Simple App',
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
initialRoute: '/',
routes: routes,
);
}
}
Below is the create_account_page.dart file
import 'package:flutter/material.dart';
import 'package:com.example.money_lender_app/models/user.dart';
class CreateAccountPage extends StatefulWidget {
final User user;
CreateAccountPage(this.user);
#override
CreateAccountPageState createState() => CreateAccountPageState(this.user);
}
//class controller
class CreateAccountPageState extends State<CreateAccountPage> {
User user;
CreateAccountPageState(this.user);
TextEditingController nameController = TextEditingController();
#override
Widget build(BuildContext context) {
//kondisi
if (user != null) {
nameController.text = user.name;
}
//rubah
return Scaffold(
appBar: AppBar(
title: user == null ? Text('Tambah') : Text('Rubah'),
leading: Icon(Icons.keyboard_arrow_left),
),
body: Padding(
padding: EdgeInsets.only(top: 15.0, left:10.0, right:10.0),
child: ListView(
children: <Widget> [
// nama
Padding (
padding: EdgeInsets.only(top:20.0, bottom:20.0),
child: TextField(
controller: nameController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Nama Lengkap',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
),
),
onChanged: (value) {
//
},
),
),
// tombol button
Padding (
padding: EdgeInsets.only(top:20.0, bottom:20.0),
child: Row(
children: <Widget> [
// tombol simpan
Expanded(
child: RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text(
'Save',
textScaleFactor: 1.5,
),
onPressed: () {
// current datetime
var currentDate = new DateTime.now();
if (user == null) {
// tambah data
user = User(nameController.text, currentDate, currentDate);
} else {
// ubah data
user.name = nameController.text;
user.created_at = currentDate;
user.updated_at = currentDate;
}
// kembali ke layar sebelumnya dengan membawa objek user
Navigator.pop(context, user);
},
),
),
Container(width: 5.0,),
// tombol batal
Expanded(
child: RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text(
'Cancel',
textScaleFactor: 1.5,
),
onPressed: () {
Navigator.pop(context);
},
),
),
],
),
),
],
),
)
);
}
}
below is the db_helper.dart file.
import 'package:sqflite/sqflite.dart';
import 'dart:async';
//mendukug pemrograman asinkron
import 'dart:io';
//bekerja pada file dan directory
import 'package:path_provider/path_provider.dart';
import 'package:com.example.simple_app/models/user.dart';
//pubspec.yml
class DbHelper {
static DbHelper _dbHelper;
static Database _database;
DbHelper._createObject();
factory DbHelper() {
if (_dbHelper == null) {
_dbHelper = DbHelper._createObject();
}
return _dbHelper;
}
Future<Database> initDb() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'simpleapp.db';
//create, read databases
var todoDatabase = openDatabase(path, version: 1, onCreate: _createDb);
return todoDatabase;
}
void _createDb(Database db, int version) async {
await db.execute('''
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
created_at DATETIME,
updated_at DATETIME
)
''');
}
Future<Database> get database async {
if (_database == null) {
_database = await initDb();
}
return _database;
}
Future<List<Map<String, dynamic>>> select() async {
Database db = await this.database;
var mapList = await db.query('user', orderBy: 'name');
return mapList;
}
//create databases
Future<int> insert(User object) async {
Database db = await this.database;
int count = await db.insert('user', object.toMap());
return count;
}
//update databases
Future<int> update(User object) async {
Database db = await this.database;
int count = await db.update('user', object.toMap(),
where: 'id=?',
whereArgs: [object.id]);
return count;
}
//delete databases
Future<int> delete(int id) async {
Database db = await this.database;
int count = await db.delete('user',
where: 'id=?',
whereArgs: [id]);
return count;
}
Future<List<User>> getUserList() async {
var userMapList = await select();
int count = userMapList.length;
List<User> userList = List<User>();
for (int i=0; i<count; i++) {
userList.add(User.fromMap(userMapList[i]));
}
return userList;
}
}
Below is the user.dart file. It is in the model folder.
class User {
int _id;
String _name;
String _username;
DateTime _created_at;
DateTime _updated_at;
// konstruktor versi 1
User(this._name, this._created_at, this._updated_at);
// konstruktor versi 2: konversi dari Map ke User
User.fromMap(Map<String, dynamic> map) {
this._id = map['id'];
this._name = map['name'];
this._created_at = map['created_at'];
this._updated_at = map['updated_at'];
}
// getter
int get id => _id;
String get name => _name;
DateTime get created_at => _created_at;
DateTime get updated_at => _updated_at;
// setter
set name(String value) {
_name = value;
}
set created_at(DateTime value) {
_created_at = value;
}
set updated_at(DateTime value) {
_updated_at = value;
}
Map<String, dynamic> toMap() {
Map<String, dynamic> map = Map<String, dynamic>();
map['id'] = this._id;
map['name'] = name;
map['created_at'] = created_at;
map['updated_at'] = updated_at;
return map;
}
}
The pubspec.yaml file has the following dependencies.
cupertino_icons: ^0.1.2
flutter_launcher_icons: ^0.7.4
sqflite: any
path_provider: ^1.5.1
The error log I'm getting in the debug console is this:
lib/main.dart:11:55: Error: Too few positional arguments: 1 required, 0 given.
'/': (BuildContext context) => new CreateAccountPage(),
^
lib/pages/create_account/create_account_page.dart:5:7: Context: Found this candidate, but the arguments don't match.
CreateAccountPage(this.user);
^^^^^^^^^^^^^^^^^
lib/main.dart:16:69: Error: Too few positional arguments: 1 required, 0 given.
'/create_account': (BuildContext context) => new CreateAccountPage(),
^
lib/pages/create_account/create_account_page.dart:5:7: Context: Found this candidate, but the arguments don't match.
CreateAccountPage(this.user);
^^^^^^^^^^^^^^^^^
I very much need to be able to pass the right argument inside the CreateAccountPage().
I'm expecting this code to work without any argument errors. Thank you!

The error says you are missing an argument when you are calling CreateAccountPage().
Its constructor is CreateAccountPage(this.user), so you need either provide a User object when you're creating the account page, or remove the parameter from the constructor.

Related

Flutter The method 'map' was called on null. Receiver: null error

I'm having this super annoying issue of being unable to grab and display a table from my server hosted on PhpmyAdmin. (I've managed to grab the data and have it printed in the console, but now that I'm trying to display it in a table I can't seem to get it working)
I've tried nulling my variables but I'm not really sure what the main culprit for this error is. Any help would be greatly appreciated.
Image of Error
data.dart File
class dataListing extends StatefulWidget {
const dataListing({Key? key}) : super(key: key);
#override
State<dataListing> createState() => _dataListingState();
}
class _dataListingState extends State<dataListing> {
#override
Widget build(BuildContext context) {
return Container();
}
}
class listingData{
String? ListingID, listingName, listingDescription, address, suburbName, phoneNumber, openingHours, Email, Website;
listingData({
this.ListingID,
this.listingName,
this.listingDescription,
this.address,
this.suburbName,
this.phoneNumber,
this.openingHours,
this.Email,
this.Website,
});
//constructor
List<listingData> datalist = [];
factory listingData.fromJSON(Map<String, dynamic> json){
return listingData(
ListingID: json["ListingID"],
listingName: json["listingName"],
listingDescription: json["listingDescription"],
address: json["address"],
suburbName: json["suburbName"],
phoneNumber: json["phoneNumber"],
openingHours: json["openingHours"],
Email: json["Email"],
Website: json["Website"],
);
}
}
Directory.dart file
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:app/pages/data.dart';
class directoryPage extends StatefulWidget {
#override
State<directoryPage> createState() => _directoryPageState();
}
class _directoryPageState extends State<directoryPage> {
// List serviceListing = [];
//
// getAllListing()async{
// String url = "URL HERE";
// var response = await http.get(Uri.parse(url));
// if (response.statusCode == 200){
// setState (() {
// serviceListing = json.decode(response.body);
// });
// print (serviceListing);
// return serviceListing;
// }
// }
bool error = false, dataloaded = false;
var data;
String dataurl = "URL HERE";
#override
void initState (){
loaddata();
super.initState();
// getAllListing();
}
void loaddata() {
Future.delayed(Duration.zero,() async {
var res = await http.post(Uri.parse(dataurl));
if (res.statusCode == 200) {
setState(() {
data = json.decode(res.body);
dataloaded = true;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Directory'),
centerTitle: true,
elevation: 0,
backgroundColor: Color(0xFFA30B32),
//WSU Appbar Icon
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset("assets/wsulogo.png", scale: 8.0),
),
),
body: Container(
padding: EdgeInsets.all(15),
child:dataloaded?datalist():
Center(
child:CircularProgressIndicator()
),
)
);
}
Widget datalist(){
if(data["error"]) {
return Text(data["errmsg"]);
}else{
List<listingData> datalist = List<listingData>.from(data["data"].map((i){
return listingData.fromJSON(i);
})
);
return Table( //if data is loaded then show table
border: TableBorder.all(width:1, color:Colors.black45),
children: datalist.map((listingdata){
return TableRow( //return table row in every loop
children: [
//table cells inside table row
TableCell(child: Padding(
padding: EdgeInsets.all(5),
child:Text(listingdata.ListingID!)
)
),
TableCell(child: Padding(
padding: EdgeInsets.all(5),
child:Text(listingdata.listingName!)
)
),
TableCell(child: Padding(
padding: EdgeInsets.all(5),
child:Text(listingdata.listingDescription!)
)
),
TableCell(child: Padding(
padding: EdgeInsets.all(5),
child:Text(listingdata.address!)
)
),
]
);
}).toList(),
);
}
}
}
Looks like the issue was actually unrelated to the dart side of things, the php code wasn't properly structuring the data. Cannot have underscores or spaces.
Correct-> $json["dballlisting"] = array (); (I renamed it to just "data" later)
Incorrect->$json["db_all_listing"] = array ();
The error seems to be originating from this line, the data['data'] is null which is expected to be an Array.
List<listingData> datalist = List<listingData>.from(data["data"].map((i){
return listingData.fromJSON(i);
})
You need to investigate your API call to make sure why it is happening. If the null value is expected then you need to add safeguards in your code to make sure it won't break when it encounter such scenarios. You can add null safety checks for that one way to do it would be to
List<listingData> datalist = List<listingData>.from((data["data"] ?? []).map((i){
return listingData.fromJSON(i);
})

Load more option in flutter ListView

I want to fetch all the infinite list view data in parts, means Initially it load 10 data item and on scroll more it should fetch next 10 items.
I am fetching data from my Laravel api and in my Laravel api endpoint there is not option for per_page, so Please help me to integrate load more option of list view data.
Here is my List data.
List<Category> _categoryList = List<Category>();
CategoryService _categoryService = CategoryService();
bool isLoading = true;
#override
void initState() {
super.initState();
_getAllCategories();
}
_getAllCategories() async {
var categories = await _categoryService.getCategories();
var result = json.decode(categories.body);
result['data'].forEach((data) {
var model = Category();
model.id = data["id"];
model.name = data["categoryName"];
model.icon = data["categoryIcon"];
setState(() {
_categoryList.add(model);
isLoading = false;
});
});
}
And I am fetching all data in simple ListTile.
child: ListView.builder(
itemCount: //_categoryList.length,
itemBuilder: (context, index) {
return ListTile(
title: _categoryList.name
);
},
),
So I have a trick and I am using it in my project. What we need here is to load more data when we are at the end of the list. So to do that we can use the ListView.builder() only:
child: ListView.builder(
itemCount: _categoryList.length + 1,
itemBuilder: (context, index) {
if(index == _categoryList.length){
// loadMore();
// return Loading();
}
return ListTile(
title: _categoryList.name
);
}),
So what we are doing is that we have set _categoryList.length + 1 to the itemCount. If _categoryList.length was 10 then we will have 11 items in the ListView and the index range will be 0 - 10. So inside the builder, we are checking that the index is equals to _categoryList.length which is 10. If the index is equals to the length of _categoryList.length, then we are at the end of the List and we can simply call some functions to load more data from Api or to show a loading widget.
I guess I got your question right, in this way you can simply lazy load data when user gets to the end of the List without using any third party libraries.
This process called pagination. Laravel provides a function for it check Pagination in Laravel
For example
$users = DB::table('users')->paginate(15);// 15 is limit per page
And check it too Paging lib in flutter dev.
I have created a sample to load more data using web service
You can see this example and you can implement for you json data.
https://android-pratap.blogspot.com/2018/12/flutter-infinite-listview-using.html
import 'package:akeepo/randomuser_infinitelist.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: InfiniteUsersList(),
);
}
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class InfiniteUsersList extends StatefulWidget {
static String tag = 'users-page';
#override
State<StatefulWidget> createState() {
return new _InfiniteUsersListState();
}
}
class _InfiniteUsersListState extends State<InfiniteUsersList> {
List<User> users = new List<User>();
ScrollController _scrollController = new ScrollController();
bool isPerformingRequest = false;
int pageNumber = 0;
#override
void initState() {
super.initState();
// Loading initial data or first request to get the data
_getMoreData();
// Loading data after scroll reaches end of the list
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_getMoreData();
}
});
}
// to show progressbar while loading data in background
Widget _buildProgressIndicator() {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Opacity(
opacity: isPerformingRequest ? 1.0 : 0.0,
child: new CircularProgressIndicator(),
),
),
);
}
#override
void dispose() {
_scrollController.dispose();
super.dispose();
}
// Webservice request to load 20 users data using paging
Future<List<User>> _getUsers() async {
List<User> users = new List<User>();
setState(() {
pageNumber++;
});
String url =
"https://api.randomuser.me/?page=$pageNumber&results=20&seed=abc";
print(url);
var response = await http.get(url);
var jsonData = json.decode(response.body);
print(jsonData);
var usersData = jsonData["results"];
for (var user in usersData) {
User newUser = User(user["name"]["first"] + user["name"]["last"],
user["email"], user["picture"]["large"], user["phone"]);
users.add(newUser);
}
return users;
}
_getMoreData() async {
if (!isPerformingRequest) {
setState(() {
isPerformingRequest = true;
});
List<User> newEntries = await _getUsers(); //returns empty list
if (newEntries.isEmpty) {
double edge = 50.0;
double offsetFromBottom = _scrollController.position.maxScrollExtent -
_scrollController.position.pixels;
if (offsetFromBottom < edge) {
_scrollController.animateTo(
_scrollController.offset - (edge - offsetFromBottom),
duration: new Duration(milliseconds: 500),
curve: Curves.easeOut);
}
}
setState(() {
users.addAll(newEntries);
isPerformingRequest = false;
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Users',
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
body: Container(
child: ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: users.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == users.length) {
return _buildProgressIndicator();
} else {
return ListTile(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
UserDetailPage(users[index])));
},
title: Text(users[index].fullName),
subtitle: Text(users[index].mobileNumber),
leading: CircleAvatar(
backgroundImage: NetworkImage(users[index].imageUrl)),
);
}
})),
);
}
}
class User {
final String fullName;
final String email;
final String imageUrl;
final String mobileNumber;
User(this.fullName, this.email, this.imageUrl, this.mobileNumber);
}
// User Detail Page
class UserDetailPage extends StatelessWidget {
final User user;
UserDetailPage(this.user);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("User Details"),
),
body: Center(
child: Text(
user.fullName,
style: TextStyle(fontSize: 35.0),
),
),
);
}
}

How can I reslove The method 'toMap' was called on null?

Why I am getting Unhandled Exception: NoSuchMethodError: The method 'toMap' was called on null this error. I stuck here but I can't understand my mistake. I think the instance of model class is not getting but Iknow why it is happening.
Model Class
class AddressModel {
int _id;
String _pin;
AddressModel(this._pin);
int get id => _id;
set id(int value) {
this._id = value;
}
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
if (_id != null) {
map['id'] = _id;
}
map['pincode'] = _pin;
return map;
}
String get pin => _pin;
set pin(String value) {
this._pin = value;
}
}
Database
class DatabaseHelper{
DatabaseHelper();
static final DatabaseHelper db = DatabaseHelper();
Database _database;
String addressTable = 'address';
String addressId = 'id';
String pinCodeColumn = 'pincode';
Future<Database> get database async {
if (_database != null) return _database;
_database = await getDatabaseInstance();
return _database;
}
Future<Database> getDatabaseInstance() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, "student.db");
return await openDatabase(path, version: 1,onCreate: _createDb);
}
void _createDb(Database db, int newVersion) async {
await db.execute('CREATE TABLE $addressTable ($addressId INTEGER PRIMARY KEY AUTOINCREMENT, $pinCodeColumn TEXT)');
}
Future<int> insertData(AddressModel note) async {
Database db = await this.database;
var result = await db.insert(addressTable, note.toMap());
return result;
}
}
Main Class
class _MyHomePageState extends State<MyHomePage> {
AddressModel model;
TextEditingController pinCode = TextEditingController();
DatabaseHelper helper = DatabaseHelper();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
child: TextField(
keyboardType: TextInputType.phone,
controller: pinCode,
onChanged: (value) {
debugPrint('Something changed in Title Text Field');
updatePin();
},
decoration: InputDecoration(
labelText: 'Pin Code *',
hintText: 'Fill your Pin Code',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
),
),
RaisedButton(
onPressed: (){
helper.insertData(model);
},
)
],
),
),
);
}
void updatePin(){
model.pin = pinCode.text;
}
}
This is the error
E/flutter (31607): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'toMap' was called on null.
E/flutter (31607): Receiver: null
E/flutter (31607): Tried calling: toMap()
E/flutter (31607): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter (31607): #1 DatabaseHelper.insertProject (package:xpecto_teasoko/databasee.dart:50:53)
Your object of AddressModel has never been initialized in _MyHomePageState, it has just been declared. You need to initialize it if you want to use that object. You can do that this way.
class _MyHomePageState extends State<MyHomePage> {
AddressModel model = AddressModel("PIN");
...
}

Snapshot.data is always returning null while getting data from sqlite database in flutter app

This keeps happening although there is data in the database. I'm new to flutter and I've been trying to fix this problem for almost three days now. snapshot.data is returning null and I don't know why because I have enough data in the database.
Below is the db_helper.dart file.
import 'dart:async';
import 'dart:io' as io;
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:com.example.simple_app/models/person.dart';
import 'package:path/path.dart';
class DBHelper {
static Database db_instance;
Future<Database> get db async {
if (db_instance == null) {
db_instance = await initDB();
}
return db_instance;
}
initDB() async {
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'simpleapp.db');
var db = await openDatabase(path, version: 1, onCreate: onCreateFunc);
return db;
}
void onCreateFunc(Database db, int version) async {
// create table
await db.execute(
'CREATE TABLE persons(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, created DATETIME, updated DATETIME);');
}
/// crud functions
Future<List<Person>> getAllPersons() async {
final db_connection = await db;
var response = await db_connection.query("Person");
List<Person> list = response.map((c) => Person.fromMap(c)).toList();
return list;
}
// add new person
void addNewPerson(Person person) async {
var db_connection = await db;
String query = """
INSERT INTO persons(name,created,updated) VALUES('${person.name}','${person.created}', '${person.updated}')
""";
await db_connection.transaction((transaction) async {
print(query);
return await transaction.rawInsert(query);
});
}
}
Below is home.dart file where I'm trying to display the data from the database in FutereBuilder but snapshot is always returning null, which is resulting in the loader circle circling all time.
import 'package:com.example.simple_app/models/person.dart';
import 'package:com.example.simple_app/utils/db_helper.dart';
import 'package:flutter/material.dart';
import 'package:com.example.simple_app/common_widgets/appbar.dart';
import 'dart:async';
import 'package:sqflite/sqflite.dart';
var dbHelper = DBHelper();
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _HomePageState();
}
}
class _HomePageState extends State<HomePage> {
int _currentIndex = 0;
final List<Widget> _children = [];
static const TextStyle moneyLendingAction =
TextStyle(color: Colors.white, fontSize: 20);
#override
Widget build(BuildContext context) {
final controller_name = new TextEditingController();
return new Scaffold(
appBar: appbar(context, 'Simple App', 'other data'),
body: new Container(
padding: EdgeInsets.all(16.0),
child: FutureBuilder<List<Person>>(
future: dbHelper.getAllPersons(),
builder:
(BuildContext context, AsyncSnapshot<List<Person>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Person item = snapshot.data[index];
return Dismissible(
background: Container(color: Colors.red),
onDismissed: (direction) {},
child: ListTile(
title: Text(item.name),
subtitle: Text(item.name),
leading: CircleAvatar(child: Text(item.id.toString())),
),
);
},
);
} else {
// because snapshot.data is returning null, this is showing all time.
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
#override
void initState() {
super.initState();
}
}
Below is the person.dart model file.
class Person {
int id;
String name;
DateTime created, updated;
Person({this.id, this.name, this.created, this.updated});
factory Person.fromMap(Map<String, dynamic> json) => new Person(
id: json["id"],
name: json["name"],
created: json["created"],
updated: json["updated"],
);
Map<String, dynamic> toMap() => {
"id": id,
"name": name,
"created": created,
"updated": updated,
};
}
What I want is to show the data from the database in the FutureBuilder. And please don't tell me this is duplicate because I have checked similar questions and I don't see any question that relates to what is happening in my code.
Thank you, posted with love.
You need to cast date strings from JSON response
created: DateTime.parse(data['created_at'].toString()),
updated: DateTime.parse(data['date'].toString()),

Getting an error while trying to get data from sqlite database in flutter app

I'm trying to get data from sqlite database using sqflite and insert it in list_view. Anything seems fine but when I add something to the database and try to get the data and put it in a list view in home.dart file, I keep getting an error.
Below is the home.dart file. This is where I'm trying to get data from database and make a list view.
The error occurs on this file.
import 'package:com.example.simple_app/models/person.dart';
import 'package:com.example.simple_app/utils/db_helper.dart';
import 'package:flutter/material.dart';
import 'package:com.example.simple_app/common_widgets/appbar.dart';
import 'package:com.example.simple_app/common_widgets/drawer.dart';
import 'dart:async';
import 'package:sqflite/sqflite.dart';
Future<List<Person>> getPersonsFromDB() async {
var dbHelper = DBHelper();
Future<List<Person>> persons = dbHelper.getPersons();
return persons;
}
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _HomePageState();
}
}
class _HomePageState extends State<HomePage> {
int _currentIndex = 0;
final List<Widget> _children = [];
static const TextStyle moneyLendingAction =
TextStyle(color: Colors.white, fontSize: 20);
final controller_name = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: appbar(context, 'Simple App', 'other data'),
body: new Container(
padding: EdgeInsets.all(16.0),
child: FutureBuilder<List<Person>>(
future: getPersonsFromDB(),
builder: (context, snapshot) {
print(snapshot.data);
if (snapshot.data != null) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return new Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(
bottom: 8.0,
),
child: Text(
snapshot.data[index].name,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
),
),
],
);
});
}
}
// show loading
// return new Container(
// alignment: AlignmentDirectional.center,
// child: new CircularProgressIndicator(),
// );
}),
),
);
}
setState(() {
_currentIndex = index;
});
}
}
Below is the db_helper.dart file.
import 'dart:async';
import 'dart:io' as io;
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:com.example.simple_app/models/person.dart';
import 'package:path/path.dart';
class DBHelper {
static Database db_instance;
Future<Database> get db async {
if (db_instance == null) db_instance = await initDB();
return db_instance;
}
initDB() async {
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo2.db');
var db = await openDatabase(path, version: 1, onCreate: onCreateFunc);
return db;
}
void onCreateFunc(Database db, int version) async {
// create table
await db.execute(
'CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, created DATETIME, updated DATETIME);');
}
/**
* crud functions
*/
Future<List<Person>> getPersons() async {
var db_connection = await db;
List<Map> list = await db_connection.rawQuery('SELECT * FROM person');
List<Person> persons = new List();
for (int i = 0; i < list.length; i++) {
Person person = new Person();
person.id = list[i]['id'];
person.name = list[i]['name'];
person.created = list[i]['created'];
person.updated = list[i]['updated'];
persons.add(person);
}
return persons;
}
// add new person
void addNewPerson(Person person) async {
var db_connection = await db;
String query = """
INSERT INTO person(name,created,updated) VALUES('${person.name}','${person.created}', '${person.updated}')
""";
await db_connection.transaction((transaction) async {
return await transaction.rawInsert(query);
});
}
// update person
void updatePerson(Person person) async {
var db_connection = await db;
String query = """
UPDATE person SET name='${person.name}',created='${person.created}',updated='${person.updated}' WHERE id=${person.id}
""";
await db_connection.transaction((transaction) async {
return await transaction.rawQuery(query);
});
}
// delete person
void deletePerson(Person person) async {
var db_connection = await db;
String query = """
DELETE FROM person WHERE id=${person.id}
""";
await db_connection.transaction((transaction) async {
return await transaction.rawQuery(query);
});
}
}
Below is the error log I'm getting in the debug console.
I/flutter (12326): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (12326): The following assertion was thrown building FutureBuilder<List<Person>>(dirty, state:
I/flutter (12326): _FutureBuilderState<List<Person>>#caa58):
I/flutter (12326): A build function returned null.
I/flutter (12326): The offending widget is:
I/flutter (12326): FutureBuilder<List<Person>>
I/flutter (12326): Build functions must never return null.
I/flutter (12326): To return an empty space that causes the building widget to fill available room, return
I/flutter (12326): "Container()". To return an empty space that takes as little room as possible, return
// and the logs go on and on below...
What I don't understand is anything seems fine but when I try to get data from sqlite database and list the data in Home Page file I keep getting an error. This may be a simple problem but because I'm new to flutter I'm failing to figure this out.
What I want is to be able to get the data from the database and put it in a list view in Home Page without getting any error. Thank you, Posted with love.
As stated, Build functions must never return null. Simply uncomment the code you have commented which will be called before the future completes:
// show loading
return new Container(
alignment: AlignmentDirectional.center,
child: new CircularProgressIndicator(),
);

Categories

Resources