How do I resolve a Sqlite Error (1) in Flutter? - flutter

Im new to flutter and first time to work with sqlite database.
I have created a todo app that is linked to a Sqlite database. It has simple cards that i can add and it works fine. The problem is, I have a delete icon, but for some reason the cards do not delete when I press the delete icon. I get the following error message in the stack:
E/SQLiteLog(22653): (1) no such table: çustomerblueprint in "DELETE FROM çustomerblueprint WHERE id == ?"
E/flutter (22653): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: DatabaseException(no such table: çustomerblueprint (code 1 SQLITE_ERROR[1]): , while compiling: DELETE FROM çustomerblueprint WHERE id == ?) sql 'DELETE FROM çustomerblueprint WHERE id == ?' args [1]
I have read for hours to try and fine a solution, but don't seem to get this one.
My code is:
Database Code
class CustomerBluePrint {
int? id;
final String title;
DateTime creationDate;
bool isChecked;
CustomerBluePrint({
this.id,
required this.title,
required this.creationDate,
required this.isChecked,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'title': title,
'creationDate': creationDate.toString(),
'isChecked': isChecked ? 1 : 0,
};
}
#override
String toString() {
return 'CustomerBluePrint(id : $id, title : $title, creationDate : $creationDate, isChecked
: $isChecked )'; // , phone : $phone, mobile : $mobile, fax : $fax, email : $email, name :
$name)';
}
}
class DatabaseConnect {
Database? _database;
Future<Database> get database async {
final dbpath = await getDatabasesPath();
const dbname = 'customerblueprint.db';
final path = join(dbpath, dbname);
_database = await openDatabase(path, version: 1, onCreate: _createDB);
return _database!;
}
Future<void> _createDB(Database db, int version) async {
await db.execute('''
CREATE TABLE todo(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
creationDate TEXT,
isChecked INTEGER
)
''');
}
Future<void> insertCustomerBluePrint(
CustomerBluePrint customerblueprint) async {
final db = await database;
await db.insert(
'customerblueprint',
customerblueprint.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<void> deleteCustomerBluePrint(
CustomerBluePrint customerblueprint) async {
final db = await database;
await db.delete(
'çustomerblueprint',
where: 'id == ?',
whereArgs: [customerblueprint.id],
);
}
Future<List<CustomerBluePrint>> getCustomerBluePrint() async {
final db = await database;
List<Map<String, dynamic>> items = await db.query(
'customerblueprint',
orderBy: 'id DESC',
);
return List.generate(
items.length,
(i) => CustomerBluePrint(
id: items[i]['id'],
title: items[i]['title'],
creationDate: DateTime.parse(items[i]['creationDate']),
isChecked: items[i]['isChecked'] == 1 ? true : false,
),
);
}
}
Customer List Code
import 'package:flutter/material.dart';
import 'library.dart';
import 'customer_card.dart';
class CustomerList extends StatelessWidget {
final Function insertFunction;
final Function deleteFunction;
final db = DatabaseConnect();
CustomerList(
{required this.insertFunction, required this.deleteFunction, Key? key})
: super(key: key);
#override
Widget build(BuildContext context) {
return Expanded(
child: FutureBuilder(
future: db.getCustomerBluePrint(),
initialData: const [],
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
var data = snapshot.data;
var datalength = data!.length;
return datalength == 0
? const Center(
child: Text('no data found'),
)
: ListView.builder(
itemCount: datalength,
itemBuilder: (context, i) => CustomerCard(
id: data[i].id,
title: data[i].title,
creationDate: data[i].creationDate,
isChecked: data[i].isChecked,
insertFunction: insertFunction,
deleteFunction: deleteFunction,
),
);
},
),
);
}
}
Customer Card Code
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'library.dart';
class CustomerCard extends StatefulWidget {
final int id;
final String title;
final DateTime creationDate;
bool isChecked;
final Function insertFunction;
final Function deleteFunction;
CustomerCard(
{required this.id,
required this.title,
required this.creationDate,
required this.isChecked,
required this.insertFunction,
required this.deleteFunction,
Key? key})
: super(key: key);
#override
_CustomerCardState createState() => _CustomerCardState();
}
class _CustomerCardState extends State<CustomerCard> {
#override
Widget build(BuildContext context) {
var anotherCustomerBluePrint = CustomerBluePrint(
id: widget.id,
title: widget.title,
creationDate: widget.creationDate,
isChecked: widget.isChecked);
return Card(
child: Row(
children: [
Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: Checkbox(
value: widget.isChecked,
onChanged: (bool? value) {
setState(() {
widget.isChecked = value!;
});
anotherCustomerBluePrint.isChecked = value!;
widget.insertFunction(anotherCustomerBluePrint);
},
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
const SizedBox(height: 5),
Text(
DateFormat('dd MMM yyyy - hh:mm aaa')
.format(widget.creationDate),
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xFF8F8F8F),
),
)
],
),
),
IconButton(
onPressed: () {
widget.deleteFunction(anotherCustomerBluePrint);
},
icon: const Icon(Icons.close),
),
],
),
);
}
}
Customer Code
This is my Homepage
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:invoice_app/customer_profile.dart';
import 'customer_list.dart';
import 'library.dart';
class Customer extends StatefulWidget {
const Customer({Key? key}) : super(key: key);
#override
_CustomerState createState() => _CustomerState();
}
class _CustomerState extends State<Customer> {
var db = DatabaseConnect();
void addItem(CustomerBluePrint customerblueprint) async {
await db.insertCustomerBluePrint(customerblueprint);
setState(() {});
}
void deleteItem(CustomerBluePrint customerblueprint) async {
await db.deleteCustomerBluePrint(customerblueprint);
setState(() {
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF5EBFF),
body: Column(
children: [
CustomerList(
insertFunction: addItem, deleteFunction: deleteItem),
CustomerProfile(
insertFunction: addItem
),
],
),
);
}
The deletefunction is suppose to delete an entry based on the 'id'assigned to it. Everything works fine, except I cannot delete a card (entry) as it throws the error.
Please help. Would really appreciate it.

Found your mistake take a look at Database Code and implementation of the method Future<void> deleteCustomerBluePrint(CustomerBluePrint customerblueprint) You have an error there. Your:
await db.delete(
'çustomerblueprint',
where: 'id == ?',
whereArgs: [customerblueprint.id],
);
Mine Repaired:
await db.delete(
'customerblueprint',
where: 'id == ?',
whereArgs: [customerblueprint.id],
);
An error in the word customerblueprint, you do not have the letter "c" there, you have some other sign.

Related

How to save image as blob in sqlite in flutter

I'm using Flutter, I need to save image in SQLite as BLOB, then display it in my page.
I did it as String and it works fine but not image with 1.5 MB size, the app get unhanded exception, I tried to do it as blob but I could not find any tutorial anywhere.
My model:
import 'package:flutter/services.dart';
const String tablePersonal = 'personal_info';
class PersonalFields {
static final List<String> values = [
id,
name,
logo,
];
static const String id = '_id';
static const String name = 'name';
static const String logo = 'logo';
}
class PersonalInfoModel {
int? id;
final String name;
final Uint8List? logo;
PersonalInfoModel({
this.id,
required this.name,
this.logo,
});
PersonalInfoModel copy({
int? id,
String? name,
Uint8List? logo,
}) =>
PersonalInfoModel(
id: id ?? this.id,
name: name ?? this.name,
logo: logo ?? this.logo,
);
static PersonalInfoModel fromJson(Map<String, Object?> json) =>
PersonalInfoModel(
id: json[PersonalFields.id] as int?,
name: json[PersonalFields.name] as String,
logo: json[PersonalFields.logo] as Uint8List?,
);
Map<String, dynamic> toJson() => {
PersonalFields.id: id,
PersonalFields.name: name,
PersonalFields.logo: logo,
};
}
SQL Helper: after create the table I just make insert null record to save the id = 1 so that I will just update the record. That is means the table will only get one record.
batch.execute('''
CREATE TABLE IF NOT EXISTS $tablePersonal
(
${PersonalFields.id} $idType,
${PersonalFields.name} $textType,
${PersonalFields.logo} $blobType
)
''');
batch.execute('''
INSERT INTO $tablePersonal
(
${PersonalFields.name}
)
VALUES
(
''
)
''');
//read personal info
Future<List<PersonalInfoModel>> getPesonalInfo() async {
var db = await instanace.database;
final result = await db.query(tablePersonal);
return result.map((json) => PersonalInfoModel.fromJson(json)).toList();
}
Future<int> updatePersonalInfo(PersonalInfoModel personalInfoModel) async {
final db = await instanace.database;
return db.update(
tablePersonal,
personalInfoModel.toJson(),
where: '${PersonalFields.id} = ?',
whereArgs: [personalInfoModel.id],
);
}
My Page:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:ledger/database/sql_helper.dart';
import 'package:ledger/l10n/app_local.dart';
import 'package:ledger/models/personal_info_model.dart';
class PersonalInfoPage extends StatefulWidget {
const PersonalInfoPage({Key? key}) : super(key: key);
#override
State<PersonalInfoPage> createState() => _PersonalInfoPageState();
}
class _PersonalInfoPageState extends State<PersonalInfoPage> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _nameController = TextEditingController();
double boxWidth = 10;
double boxHieght = 10;
XFile? xImage;
var bytes;
final ImagePicker _picker = ImagePicker();
late List<PersonalInfoModel> personalList;
late PersonalInfoModel existPersonal;
bool isLoading = true;
#override
void initState() {
super.initState();
getPersonalInfo();
}
Future pickImage() async {
try {
xImage = await _picker.pickImage(source: ImageSource.gallery);
if (xImage == null) return;
final imagePath = File(xImage!.path);
bytes = imagePath;
setState(() {});
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
Future getPersonalInfo() async {
final data = await SQLHelper.instanace.getPesonalInfo();
setState(() {
personalList = data;
getData();
isLoading = false;
});
}
getData() {
existPersonal = personalList.firstWhere((element) => element.id == 1);
_nameController.text = existPersonal.name;
bytes = existPersonal.logo;
}
Future updatePersonalInfo(PersonalInfoModel personalInfoModel) async {
await SQLHelper.instanace.updatePersonalInfo(personalInfoModel);
getPersonalInfo();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocal.loc.personal_info),
actions: [
IconButton(
onPressed: () {
PersonalInfoModel personalInfoModel = PersonalInfoModel(
id: 1,
name: _nameController.text,
logo: bytes);
updatePersonalInfo(personalInfoModel);
},
icon: const Icon(Icons.save_as_outlined),
),
],
),
body: isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: Form(
key: _formKey,
child: Column(
children: [
SizedBox(height: boxHieght),
TextFormField(
controller: _nameController,
decoration: InputDecoration(
filled: true,
labelText: AppLocal.loc.name,
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
print('xxxxxx');
pickImage();
},
child: Text('from Gallary'),
),
],
),
Container(
color: Colors.grey.shade100,
height: 150,
width: 150,
child: bytes != null
? Image.memory(bytes)
: Image.asset('assets/logo.png'),
),
],
),
),
);
}
}
Here is how you can convert it into a blob and save it to SQLite
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker.pickImage(source: source);
final imagePath = File(image.path);
List<int> bytes = await image.readAsBytes();
String base64 = base64Encode(bytes);// here it is. Save it to sqflite
} on PlatformException catch (e) {
print(e);
}
}
for getting from SQLite
String blobImageFromSqflite; //get from sqflite
Uint8List _bytesImage = Base64Decoder().convert(blobImageFromSqflite);
to display it;
Image.memory(
_bytesImage,
);

the variable date of DateTime doesn't save when I press on cold reload

I used Share_Prefereces library so I want to save date of adding Item. I tried many ways but
I always get the errors: E/flutter ( 2786): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'DateTime'
and the second error is: Unhandled Exception: Converting object to an encodable object failed: Instance of 'Shopping'
so please help me
the code of Date file is:
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Shopping {
String item;
int price;
DateTime date;
Shopping({required this.item, required this.price, required this.date});
Map<String, dynamic> toJson() {
return {
'item': item,
'price': price,
'date': date,
};
}
}
class ItemData extends ChangeNotifier {
List<Shopping> listOfItem = [];
void addItem(Shopping shopping) {
listOfItem.add(shopping);
notifyListeners();
}
void editItem(Shopping shopping, int itemIndex) {
listOfItem[itemIndex] = shopping;
notifyListeners();
}
void deleteItem(int itemIndex) {
listOfItem.removeAt(itemIndex);
notifyListeners();
}
saveData() async {
SharedPreferences pref = await SharedPreferences.getInstance();
List<String> tempList = [];
for (int i = 0; i < listOfItem.length; i++) {
tempList.add(jsonEncode(listOfItem[i]));
}
pref.remove("itemList");
pref.setStringList("itemList", tempList);
}
loadData() async {
SharedPreferences pref = await SharedPreferences.getInstance();
if (pref.getStringList('itemList') != null) {
List<String> tempList = pref.getStringList('itemList')!;
for (int i = 0; i < tempList.length; i++) {
Map<String, dynamic> temp = jsonDecode(tempList[i]);
addItem(
Shopping(
item: temp['item'],
price: temp['price'],
date: temp['date'],
),
);
}
}
}
}
and the code of adding Item, price and date is:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:goods_and_price/shopping_data.dart';
import 'package:provider/provider.dart';
class AddItem extends StatelessWidget {
AddItem({Key? key}) : super(key: key);
TextEditingController userInputItem = TextEditingController();
TextEditingController userInputPrice = TextEditingController();
#override
Widget build(BuildContext context) {
var provider = Provider.of<ItemData>(context, listen: true);
DateTime date = DateTime.now();
return Scaffold(
appBar: AppBar(
title: const Text('Add Item'),
centerTitle: true,
backgroundColor: const Color(0xFF00899C),
),
body: ListView(
physics: const BouncingScrollPhysics(),
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: userInputItem,
decoration: InputDecoration(
hintText: 'Item',
labelText: 'Item',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
prefixIcon: const Icon(
Icons.shopping_cart,
color: Color(0xFF00899C),
)),
maxLines: null,
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: userInputPrice,
decoration: InputDecoration(
hintText: 'Price',
labelText: 'Price',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
prefixIcon: const Icon(
Icons.attach_money,
color: Color(0xFF00899C),
)),
maxLines: null,
),
),
const SizedBox(
height: 10,
),
CupertinoButton(
padding: const EdgeInsets.all(0),
pressedOpacity: 0.5,
child: Container(
height: 50,
width: 120,
decoration: BoxDecoration(
color: const Color(0xFF00899C),
borderRadius: BorderRadius.circular(10)),
child: const Center(
child: Text(
'Add Item',
style: TextStyle(color: Colors.white),
),
),
),
onPressed: () async {
Shopping newItem = Shopping(
item: userInputItem.text,
price: int.parse(userInputPrice.text),
date: date,
);
provider.addItem(newItem);
provider.saveData();
Navigator.pop(context);
},
),
],
),
);
}
}
I don't recommend using DateTime, because it takes a certain amount of work to use in different languages, I find it easier to use String.
I couldn't simulate the error on my machine, but I made an example, I hope it helps.
To create class I like to use this site https://javiercbk.github.io/json_to_dart/
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:zoociadoleite_app/global/my_app.dart';
class TesteScreen extends StatefulWidget {
const TesteScreen({Key key}) : super(key: key);
#override
State<TesteScreen> createState() => _TesteScreenState();
}
class Shopping {
String item;
int price;
String date;
Shopping({this.item, this.price, this.date});
Shopping.fromJson(Map<String, dynamic> json) {
item = json['item'];
price = json['price'];
date = json['date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['item'] = this.item;
data['price'] = this.price;
data['date'] = this.date;
return data;
}
}
class LocalStorage {
Future<String> get(String item) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(item);
}
Future<bool> set(String item, dynamic data) async {
final prefs = await SharedPreferences.getInstance();
return prefs.setString(item, json.encode(data));
}
Future<bool> remove(String item) async {
final prefs = await SharedPreferences.getInstance();
return prefs.remove(item);
}
}
class _TesteScreenState extends State<TesteScreen> {
final formatDate = new DateFormat.yMMMMd('pt_BR');
Future<List<Shopping>> _future;
List<Shopping> list = [];
load() async {
String data = await LocalStorage().get("Shopping");
if (data != null) {
List<dynamic> lista = json.decode(data) as List;
list = lista.map((shopping) => Shopping.fromJson(shopping)).toList();
}
_future = Future.value(list);
setState(() {});
}
#override
void initState() {
super.initState();
load();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Shopping>>(
future: _future,
builder: (context, snapshot) {
if (snapshot.hasData)
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Shopping shopping = snapshot.data[index];
return ListTile(
title: Text(shopping.item),
subtitle: Text("${shopping.price}"),
trailing: Text("${formatDate.format(DateTime.parse(shopping.date))}"),
);
},
);
return CircularProgressIndicator();
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
list.add(Shopping(item: "test_${list.length + 1}", price: list.length + 1, date: DateTime.now().toString()));
_future = Future.value(list);
LocalStorage().set("Shopping", list);
setState(() {});
},
child: const Icon(Icons.add),
),
);
}
}

Getting a getter length is called on Null error when trying to access List on Firebase using flutter

I am trying to retrieve and display a list of items on firebase, I have been able to access everything else on firebase apart from the list itself. I think the issue might be how I am going about retrieving the list because of the method in which it was saved. Here is the order model code
import 'package:butcherbox/models/productsModel.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:meta/meta.dart';
class Order {
Order(
{#required this.items,
//this.theItems,
this.location,
this.orderId,
this.time,
#required this.price});
final List<ProductsModel> items;
final String location;
final int orderId;
final Timestamp time;
final int price;
factory Order.fromMap(Map<String, dynamic> data) {
if (data == null) {
return null;
}
final List<ProductsModel> items = data['items'];
final String location = data['location'];
final int price = data['price'];
final int orderId = data['orderId'];
final Timestamp time = data['time'];
return Order(
items: items,
location: location,
price: price,
orderId: orderId,
time: time,
);
}
Map<String, dynamic> toMap() {
return {
'item': items.map((e) => e.toJson()).toList(),
'location': location,
'orderId': orderId,
'time': time,
'price': price
};
}
}
This is the code to display the data
import 'package:butcherbox/butch_widgets/order_list_tile.dart';
import 'package:butcherbox/models/ordersmodel.dart';
import 'package:butcherbox/services/database.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class Orders extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.green[200],
title: Text(
'Orders',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.green[900]),
),
),
body: _buildContents(context),
);
}
Widget _buildContents(BuildContext context) {
final database = Provider.of<Database>(context, listen: false);
return StreamBuilder<List<Order>>(
stream: database.ordersStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final orders = snapshot.data;
// final children =
// orders.map((order) => Text(order.location)).toList();
final children =
orders.map((order) => OrderListTile(order: order)).toList();
return ListView(children: children);
}
if (snapshot.hasError) {
return Center(child: Text('Some Error Occurred'));
}
return Center(child: CircularProgressIndicator());
});
}
}
This is the widget for the UI
import 'package:butcherbox/models/ordersmodel.dart';
import 'package:flutter/material.dart';
class OrderListTile extends StatelessWidget {
final Order order;
const OrderListTile({Key key, #required this.order}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(
'Order No: ${order.orderId}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.green[900]),
),
trailing: Text(
'Vendor: ${order.location}',
style: TextStyle(fontSize: 16),
),
subtitle: ListView.builder(
itemCount: order.items.length, <-- This is where the error is
shrinkWrap: true,
itemBuilder: (context, i) {
return Expanded(
child: Column(
children: [
Text('${order.items[i].name}'),
Text('${order.items[i].quantity.toString()}')
],
),
);
}),
isThreeLine: true,
);
}
}
This is the database code
import 'package:butcherbox/models/ordersmodel.dart';
import 'package:butcherbox/services/api_path.dart';
import 'package:meta/meta.dart';
import 'package:butcherbox/services/firestore_service.dart';
abstract class Database {
Future<void> createOrder(Order order);
Stream<List<Order>> ordersStream();
}
String docFromId() => DateTime.now().toIso8601String();
class FireStoreDatabase implements Database {
FireStoreDatabase({#required this.uid}) : assert(uid != null);
final String uid;
final _service = FireStoreService.instance;
Future<void> createOrder(Order order) => _service.setData(
//path: APIPath.order(uid, 'orderdetails'), data: order.toMap());
path: APIPath.order(uid, docFromId()),
data: order.toMap(),
);
Stream<List<Order>> ordersStream() => _service.collectionStream(
path: APIPath.orders(uid), builder: (data) => Order.fromMap(data));
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
class FireStoreService {
FireStoreService._();
static final instance = FireStoreService._();
Future<void> setData({String path, Map<String, dynamic> data}) async {
final reference = FirebaseFirestore.instance.doc(path);
print('$path: $data');
await reference.set(data);
}
Stream<List<T>> collectionStream<T>({
#required String path,
#required T Function(Map<String, dynamic> data) builder,
}) {
final reference = FirebaseFirestore.instance.collection(path);
final snapshots = reference.snapshots();
return snapshots.map((snapshot) => snapshot.docs
.map(
(snapshot) => builder(snapshot.data()),
)
.toList());
}
}
Yes actually you are right, so here are some keypoints,
Stream<List<Order>> ordersStream() => _service.collectionStream(
path: APIPath.orders(uid), builder: (data) =>
// This is supposed to be a list of Orders.
Order.fromMap(data));
You can try printing the data here so you see what I am talking about(it would be a List and not a singular object).

Null value is saving instead of entered value in Flutter

I am receiving a null values when I am calling the getItems() method in database_client.dart file (retrieving all items name) ...so basically I am dealing with just two functions here which are saveItem() and getItems(). But itemName is storing in db as null value and i don't know why it is getting it as a null value ... there is no error in my code but the problem is that null values I am receiving of _itemName_and _dateCreated fields which are present in nodo_item.dart file.
I am going to give you my whole project code so that you can easily find out the problem here.
main.dart
import 'package:flutter/material.dart';
import 'package:no_to_do_app/ui/home.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'NotoDo',
home: new Home(),
);
}
}
home.dart
import 'package:flutter/material.dart';
import 'package:no_to_do_app/ui/notodo_screen.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: Text('NoToDo'),
backgroundColor: Colors.black54,
),
body: new NoToDoScreen(
)
);
}
}
nodo_item.dart
import 'package:flutter/material.dart';
class NoDoItem extends StatelessWidget {
late String? _itemName;
late String? _dateCreated;
int? _id;
NoDoItem( this._itemName , this._dateCreated, {Key? key}) : super(key: key);
NoDoItem.map(dynamic obj, {Key? key}) : super(key: key)
{
_itemName = obj['ItemName'];
_dateCreated = obj['DateCreated'];
_id = obj['id'];
}
String? get itemName => _itemName;
String? get dateCreated => _dateCreated;
int? get id => _id;
Map<String , dynamic>toMap()
{
var map = <String , dynamic>{};
map['ItemName'] = _itemName;
map['DateCreated'] = _dateCreated;
/*if(_id !=null)
{
map['id'] = _id;
}*/
map['id'] = _id;
return map;
}
NoDoItem.fromMap(Map<String , dynamic>map, {Key? key}) : super(key: key)
{
_itemName = map['ItemName'];
_dateCreated = map['DateCreated'];
_id = map['id'];
}
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(_itemName! ,
style: const TextStyle(
color: Colors.white,
fontSize: 16.5,
fontWeight: FontWeight.bold
),),
Container(
margin: const EdgeInsets.only(top: 5.0),
child: Text('Created on: $_dateCreated',
style: const TextStyle(
color: Colors.white70,
fontStyle: FontStyle.italic,
fontSize: 13.4
),),
)
],
)
);
}
}
database_client.dart
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:no_to_do_app/model/nodo_item.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper
{
static final DatabaseHelper _instance = DatabaseHelper.private();
DatabaseHelper.private();
factory DatabaseHelper() => _instance;
final String tableName = "nodoTbl";
final String columnId = "id";
final String columnItemName = "itemName";
final String columnDateCreated = "dateCreated";
static late Database _db;
Future<Database> get database async
{
/*if(_db!=null)
{
return _db;
}*/
_db =await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async
{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "notodo_db.db");
var ourDb= await openDatabase(path , version: 1 , onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async
{
await db.execute(
"CREATE TABLE $tableName(id INTEGER PRIMARY KEY , $columnItemName TEXT ,$columnDateCreated TEXT)"
);
debugPrint('Table is Created');
}
Future<int> saveItem(NoDoItem item) async
{
var dbClient = await database;
int res =await dbClient.insert(tableName, item.toMap());
debugPrint(res.toString());
return res;
}
Future<List> getItems() async
{
var dbClient = await database;
var result = await dbClient.rawQuery("SELECT * FROM $tableName ORDER BY $columnItemName ASC");
return result.toList();
}
Future<int?> getCount() async
{
var dbClient = await database;
return Sqflite.firstIntValue(await dbClient.rawQuery(
"SELECT COUNT(*) FROM $tableName"
));
}
Future<NoDoItem?> getItem(int id) async{
var dbClient = await database;
var result = await dbClient.rawQuery("SELECT * FROM $tableName WHERE id=$id");
//if(result.length==0) return null;
if(result.isEmpty) return null;
return NoDoItem.fromMap(result.first);
}
Future<int> deleteItem(int id) async
{
var dbClient =await database;
return await dbClient.delete(tableName,where: "$columnId = ?", whereArgs: [id]);
}
Future<int> updateItem(NoDoItem item) async
{
var dbClient =await database;
return await dbClient.update(tableName, item.toMap(),
where: "$columnId=?", whereArgs: [item.id]);
}
Future close() async
{
var dbClient =await database;
return dbClient.close();
}
}
notodo_screen.dart
import 'package:flutter/material.dart';
import 'package:no_to_do_app/model/nodo_item.dart';
import 'package:no_to_do_app/util/database_client.dart';
class NoToDoScreen extends StatefulWidget {
const NoToDoScreen({Key? key}) : super(key: key);
#override
_NoToDoScreenState createState() => _NoToDoScreenState();
}
class _NoToDoScreenState extends State<NoToDoScreen> {
final TextEditingController _textEditingController = TextEditingController();
var db = DatabaseHelper();
#override
void initState() {
// TODO: implement initState
super.initState();
_readNotoDoItems();
}
void _hndleSubmitted(String text) async
{
_textEditingController.clear();
NoDoItem noDoItem = NoDoItem(text, DateTime.now().toIso8601String());
int savedItemId = await db.saveItem(noDoItem);
debugPrint("Item saved ID: $savedItemId");
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black87,
body: Column(),
floatingActionButton: FloatingActionButton(
tooltip: 'Add Item',
backgroundColor: Colors.redAccent,
child: const ListTile(
title: Icon(Icons.add)
),
onPressed: _showFormDialog),
);
}
void _showFormDialog() {
var alert = AlertDialog(
content: Row(
children: [
Expanded(
child: TextField(
controller: _textEditingController,
autofocus: true,
decoration: const InputDecoration(
labelText: 'item',
hintText: "eg. Don't buy Stuff",
icon: Icon(Icons.add_circle_outline_outlined)
),
))
],
),
actions: [
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
),
onPressed: () {
_hndleSubmitted(_textEditingController.text);
_textEditingController.clear();
},
child: const Text("Save"),
),
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
),
onPressed: () => Navigator.pop(context),
child: const Text("Cancel"),)
]
);
showDialog(context: context,
builder: (_) {
return alert;
});
}
_readNotoDoItems() async
{
List items = await db.getItems();
items.forEach((item) {
NoDoItem noDoItem = NoDoItem.map(item);
print("Db items: ${noDoItem.itemName}");
});
}
}
Output I am getting after running the project:
Performing hot restart...
Syncing files to device Android SDK built for x86...
Restarted application in 8,386ms.
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
I/flutter ( 3831): Db items: null
D/InputConnectionAdaptor( 3831): The input method toggled cursor monitoring on
I/TextInputPlugin( 3831): Composing region changed by the framework. Restarting the input method.
W/IInputConnectionWrapper( 3831): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper( 3831): getTextBeforeCursor on inactive InputConnection
D/InputConnectionAdaptor( 3831): The input method toggled cursor monitoring on
I/flutter ( 3831): 12
I/flutter ( 3831): Item saved ID: 12

Flutter null check operator used on null value

This is my first month as coder. I am trying to develop nearby places app. When i used following codes im getting error of "null check operator used on a null value". But based on what i see or when i printed url and checked manually or when i used if condition i see no problem or no error. Just when i rendered screen im getting this error. I would like to ask if someone can point me what is wrong ? Thanks in advance!
The line im getting error is locationName: locationSuggestion!.query.pages[0]!.title. Probibly and following locationSuggestion class.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_data_final.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_names.dart';
import 'package:flutter_udemy_examples/screens/login_ekrani.dart';
import 'package:flutter_udemy_examples/screens/map_screen.dart';
import 'login_ekrani.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../banner.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_udemy_examples/http_api_data/get_location_images.dart';
// ignore: must_be_immutable
class HomeScreen extends StatefulWidget {
#override
State<HomeScreen> createState() => HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
LocationDataFinal? locationSuggestion;
bool isLoading = true;
#override
void initState() {
super.initState();
asyncInitState();
}
Future<void> asyncInitState() async {
await fecthlocationData();
}
Future fecthlocationData() async {
var locations = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
final double enlem = locations.latitude;
final double boylam = locations.longitude;
final url = Uri.parse(
"https://en.wikipedia.org/w/api.php?action=query&format=json&prop=coordinates%7Cpageimages%7Cdescription%7Cextracts&generator=geosearch&piprop=original&descprefersource=central&exlimit=20&exintro=1&explaintext=1&exsectionformat=plain&ggscoord=${enlem}%7C${boylam}&ggsradius=10000");
print(url);
final response = await http.get(url);
//print(response.body);
if (response.statusCode == 200) {
locationSuggestion = await locationDataFinalFromJson(response.body);
if (locationSuggestion != null) {
setState(() {
isLoading = false;
});
} else {
print("null1");
}
} else {
print("null2");
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: _buildAppBar(context),
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: ListView(
children: [
MyBanner(
// info: locationSuggestion!.query.pages[0]!.description,
locationName: locationSuggestion!.query.pages[0]!.title,
imagePath:
locationSuggestion!.query.pages[0]!.original.source,
context: context,
),
MyBanner(
//info: locationSuggestion!.query.pages[1]!.description,
locationName: locationSuggestion!.query.pages[1]!.title,
imagePath:
locationSuggestion!.query.pages[1]!.original.source,
context: context,
),
MyBanner(
// info: locationSuggestion!.query.pages[2]!.description,
locationName: locationSuggestion!.query.pages[2]!.title,
imagePath:
locationSuggestion!.query.pages[2]!.original.source,
context: context,
),
MyBanner(
// info: locationSuggestion!.query.pages[3]!.description,
locationName: locationSuggestion!.query.pages[3]!.title,
imagePath:
locationSuggestion!.query.pages[3]!.original.source,
context: context,
),
MyBanner(
// info: locationSuggestion!.query.pages[4]!.description,
locationName: locationSuggestion!.query.pages[4]!.title,
imagePath:
locationSuggestion!.query.pages[4]!.original.source,
context: context,
),
],
),
);
}
AppBar _buildAppBar(BuildContext context) {
return AppBar(
automaticallyImplyLeading: false,
leading: RotatedBox(
quarterTurns: 2,
child: _buildExitButton(context),
),
actions: [
_buildOpenMapButton(),
_buildCallEmergencyNumberButton(),
],
titleSpacing: 25,
shadowColor: Colors.white,
elevation: 0.0,
backgroundColor: Colors.blue[800],
//titleSpacing: Padding(padding: EdgeInsets.fromLTRB(25.85.0, 0, 25.85.0, 0)),
title: Text("Traveler Doctor"),
);
}
Widget _buildCallEmergencyNumberButton() {
return IconButton(
disabledColor: Colors.red,
color: Colors.red,
icon: Icon(Icons.phone_enabled),
tooltip: "Local emergency number",
onPressed: null,
);
}
Widget _buildOpenMapButton() {
return IconButton(
disabledColor: Colors.orangeAccent,
color: Colors.limeAccent,
icon: Icon(Icons.map_rounded),
tooltip: "Map",
enableFeedback: false,
onPressed: () => {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) => MapScreen()))
},
);
}
}
Widget _buildExitButton(BuildContext context) {
return IconButton(
onPressed: () async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('KullaniciAdi', "");
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => LoginEkrani()));
},
icon: Icon(
Icons.exit_to_app,
color: Colors.red,
),
tooltip: "Exit",
);
}
And this is the model im using for parsing api response
import 'dart:convert';
LocationDataFinal locationDataFinalFromJson(String str) =>
LocationDataFinal.fromJson(json.decode(str));
class LocationDataFinal {
LocationDataFinal({
required this.batchcomplete,
required this.query,
});
String batchcomplete;
Query query;
factory LocationDataFinal.fromJson(Map<String, dynamic> json) =>
LocationDataFinal(
batchcomplete: json["batchcomplete"],
query: Query.fromJson(json["query"]),
);
}
class Query {
Query({
required this.pages,
});
Map<String, Page> pages;
factory Query.fromJson(Map<String, dynamic> json) => Query(
pages: Map.from(json["pages"])
.map((k, v) => MapEntry<String, Page>(k, Page.fromJson(v))),
);
}
class Page {
Page({
required this.pageid,
required this.ns,
required this.title,
required this.index,
required this.coordinates,
required this.original,
required this.description,
required this.descriptionsource,
required this.extract,
});
int pageid;
int ns;
String title;
int index;
List<Coordinate> coordinates;
Original original;
String description;
String descriptionsource;
String extract;
factory Page.fromJson(Map<String, dynamic> json) => Page(
pageid: json["pageid"],
ns: json["ns"],
title: json["title"],
index: json["index"],
coordinates: List<Coordinate>.from(
json["coordinates"].map((x) => Coordinate.fromJson(x))),
original: json["original"] == null
? Original(
source:
"https://tigres.com.tr/wp-content/uploads/2016/11/orionthemes-placeholder-image-1.png",
width: 300,
height: 200)
: Original.fromJson(json["original"]),
description: json["description"] == null ? "asd" : json["description"],
descriptionsource:
json["descriptionsource"] == null ? " " : json["descriptionsource"],
extract: json["extract"],
);
}
class Coordinate {
Coordinate({
required this.lat,
required this.lon,
required this.primary,
required this.globe,
});
double lat;
double lon;
String primary;
Globe globe;
factory Coordinate.fromJson(Map<String, dynamic> json) => Coordinate(
lat: json["lat"].toDouble(),
lon: json["lon"].toDouble(),
primary: json["primary"],
globe: globeValues.map[json["globe"]]!,
);
}
enum Globe { EARTH }
final globeValues = EnumValues({"earth": Globe.EARTH});
class Original {
Original({
required this.source,
required this.width,
required this.height,
});
String source;
int width;
int height;
factory Original.fromJson(Map<String, dynamic> json) => Original(
source: json["source"],
width: json["width"],
height: json["height"],
);
}
class EnumValues<T> {
late Map<String, T> map;
late Map<T, String> reverseMap;
EnumValues(this.map);
}
I will be checking this post frequently.
Thanks in advance again.
Sincerely ur noob coder.
Would leave this as a comment but apparently I only have enough reputation to write answers.
In your Query object pages is a Map<String, Page> but you're accessing it with a int key: locationSuggestion!.query.pages[0]!.title
To access the map with an int key, it needs to be Map<int,Page> (or List<Page>)
Somewhat i solved issue by replacing
locationSuggestion!.query.pages[0]!.titlewith
locationSuggestion!.query.pages.values.elementAt(0).title
This way of adressing solved issue for me :)