How to show list item to another page - sql

From the code below, when I create user(student) data It will show up as a list. Each student information will be shown by a ListTile widget. When I slide and press the completed button on the ListTile, I want my ListTile to show on the 'Completed' page list view. I am currently working with sqlite. I am having a hard time trying to figure this out.
main.dart
import 'package:flutter/material.dart';
import '../database/db.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return (MaterialApp(
home: Scaffold(
body: PageView(children: <Widget>[Home(), Completed()]),
)));
}
}
//Uncompleted
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text("Students"),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddInfo()),
).then((value) {
setState(() {});
});
},
icon: Icon(Icons.add),
)
],
),
body: userInfoBuilder(context),
);
}
Future<List<UserInfo>> loadUserInfo() async {
DBHelper sd = DBHelper();
return await sd.userInfo();
}
Future<void> deleteUserInfo(String id) async {
DBHelper sd = DBHelper();
sd.deleteUserInfo(id);
}
Widget userInfoBuilder(BuildContext parentContext) {
return FutureBuilder<List<UserInfo>>(
builder: (context, snap) {
if (snap.data == null || snap.data.isEmpty) {
return Container();
}
return ListView.builder(
itemCount: snap.data.length,
itemBuilder: (context, index) {
UserInfo userInfo = snap.data[index];
return Slidable(
actionPane: SlidableBehindActionPane(),
actions: <Widget>[
IconSlideAction(
caption: 'delete',
icon: Icons.delete,
color: Colors.red,
onTap: () {
setState(() {
deleteUserInfo(userInfo.id);
});
})
],
secondaryActions: <Widget>[
IconSlideAction(
caption: 'completed',
icon: Icons.check,
color: Colors.green,
onTap: () {}),
],
child: ListTile(
title: Text(
userInfo.name,
style: TextStyle(
fontSize: 18.0,
),
),
trailing: Text(
'${userInfo.grade}-${userInfo.classnum}-${userInfo.studentnum}',
style: TextStyle(color: Colors.grey),
),
),
);
},
);
},
future: loadUserInfo(),
);
}
}
//completed
class Completed extends StatefulWidget {
#override
_CompletedState createState() => _CompletedState();
}
class _CompletedState extends State<Completed> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text(
"Completed",
),
),
body: userInfoBuilder(context),
);
}
Widget userInfoBuilder(BuildContext parentContext) {
return FutureBuilder<List<UserInfo>>(
builder: (context, snap) {
if (snap.data == null || snap.data.isEmpty) {
return Container();
}
return ListView.builder();
},
future: loadUserInfo(),
);
}
Future<List<UserInfo>> loadUserInfo() async {
DBHelper sd = DBHelper();
return await sd.userInfo();
}
}
//Add user information
class AddInfo extends StatefulWidget {
#override
_AddInfoState createState() => _AddInfoState();
}
class _AddInfoState extends State<AddInfo> {
hideKeyboard() {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}
final formKey = GlobalKey<FormState>();
String _grade;
final List<String> _grades = ['1', '2', '3'];
String name = '';
String classNum = ' ';
String studentNum = ' ';
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
hideKeyboard();
},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
hideKeyboard();
})),
body: Form(
key: formKey,
child: Column(
children: <Widget>[
usrNameField(),
Row(
children: <Widget>[
Expanded(child: usrGradeField()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
),
Expanded(child: usrClassField()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
),
Expanded(child: usrNumField()),
],
),
submitButton()
],
),
),
));
}
Widget usrNameField() {
return TextFormField(
keyboardType: TextInputType.name,
decoration: InputDecoration(
labelText: 'name',
),
onChanged: (String name) {
this.name = name;
},
validator: (input) => input.trim().isEmpty ? 'Enter name' : null);
}
Widget usrGradeField() {
return DropdownButtonFormField(
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 22.0,
items: _grades.map((String grade) {
return DropdownMenuItem(
value: grade,
child: Text(
grade,
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
);
}).toList(),
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Grade',
),
validator: (input) => input.trim().isEmpty ? 'Enter grade.' : null,
onChanged: (value) {
setState(() {
_grade = value;
});
},
value: _grade,
);
}
Widget usrClassField() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Class',
),
validator: (input) => input.trim().isEmpty ? 'Enter class.' : null,
onChanged: (String classNum) {
this.classNum = classNum;
},
);
}
Widget usrNumField() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Number',
),
validator: (input) => input.trim().isEmpty ? 'Enter number' : null,
onChanged: (String studentNum) {
this.studentNum = studentNum;
},
);
}
Widget submitButton() {
return MaterialButton(
color: Colors.blue,
child: Text(
'submit',
style: TextStyle(color: Colors.white),
),
onPressed: () {
hideKeyboard();
if (formKey.currentState.validate()) {
saveDB();
Navigator.pop(context);
}
},
);
}
Future<void> saveDB() async {
DBHelper sd = DBHelper();
var fido = UserInfo(
id: str2sha512(DateTime.now().toString()),
name: this.name,
grade: this._grade,
classnum: this.classNum,
studentnum: this.studentNum,
);
await sd.insertUserInfo(fido);
print(await sd.userInfo());
}
String str2sha512(String text) {
var bytes = utf8.encode(text);
var digest = sha512.convert(bytes);
return digest.toString();
}
}
db.dart
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class UserInfo {
final String id;
final String name;
final String grade;
final String classnum;
final String studentnum;
UserInfo({
this.id,
this.name,
this.grade,
this.classnum,
this.studentnum,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'grade': grade,
'classnum': classnum,
'studentnum': studentnum,
};
}
#override
String toString() {
return 'userInfo{id: $id, name: $name, grade: $grade, classnum: $classnum, studentnum: $studentnum}';
}
}
final String TableName = 'userInfo';
class DBHelper {
var _db;
Future<Database> get database async {
if (_db != null) return _db;
_db = openDatabase(
join(await getDatabasesPath(), 'userInfo.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE userInfo(id TEXT PRIMARY KEY, name TEXT, grade TEXT, classnum TEXT, studentnum TEXT, phonenumber TEXT, status INTEGER)",
);
},
version: 1,
);
return _db;
}
Future<void> insertUserInfo(UserInfo userInfo) async {
final db = await database;
await db.insert(
TableName,
userInfo.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<UserInfo>> userInfo() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('userInfo');
return List.generate(maps.length, (i) {
return UserInfo(
id: maps[i]['id'],
name: maps[i]['name'],
grade: maps[i]['grade'],
classnum: maps[i]['classnum'],
studentnum: maps[i]['studentnum'],
);
});
}
Future<void> updateUserInfo(UserInfo userInfo) async {
final db = await database;
await db.update(
TableName,
userInfo.toMap(),
where: "id = ?",
whereArgs: [userInfo.id],
);
}
Future<void> deleteUserInfo(String id) async {
final db = await database;
await db.delete(
TableName,
where: "id = ?",
whereArgs: [id],
);
}
}

You can use the Provider package to listen to changes on your app and notify any listeners and update the UI here's A link to an example from the flutter devs

Related

The box "name" is already open and of type Box<dynamic>

The error is The box "todo_box" is already open and of type Box.
The relevant error-causing widget was: MyHomePage MyHomePage:file:///D:/Flutter_app/alimi_final/lib/schedule.dart:27:13
When the exception was thrown, this was the stack:
I have no idea about this error.
my code
main.dart
import 'package:hive/hive.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:work_a/map.dart';
import 'package:work_a/schedule.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
import 'package:work_a/screens/list_screen.dart';
import 'package:hive_flutter/hive_flutter.dart';
//const bool kIsWeb = identical(0, 0.0);
//Future<Box> openHiveBox(todo_box) async {
//if (!kIsWeb && !Hive.isBoxOpen(todo_box))
//Hive.init((await getApplicationDocumentsDirectory()).path);
//return await Hive.openBox(todo_box);
//}
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
final appDocumentDirectory = await getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
await Hive.initFlutter();
Hive.registerAdapter(TodoAdapter());
await Hive.openBox('todo_box');
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _alimihomeState();
}
class _alimihomeState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'allimi',
theme: ThemeData(primaryColor: Colors.blue),
home: MyAppBar(),
debugShowCheckedModeBanner: false,
);
}
}
class MyAppBar extends StatelessWidget {
const MyAppBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('알리미'),
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
centerTitle: true,
elevation: 0.0,
),
drawer: Drawer(
child: ListView(
children: [
UserAccountsDrawerHeader(
currentAccountPicture: CircleAvatar(
backgroundImage: AssetImage('images/userimage.jpg'),
),
accountName: Text('한동대생'),
accountEmail: Text('00000000#handong.ac.kr'),
decoration: BoxDecoration(
color: Color.fromRGBO(31, 39, 76, 1.0),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0),
),
),
),
ListTile(
leading: Icon(
Icons.circle,
color: Colors.black,
size: 10.0,
),
visualDensity: VisualDensity(vertical: -3),
horizontalTitleGap: 1.0,
title: Text('내 스케줄'),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => schedule()),
);
},
),
SizedBox(
height: 5.0,
),
ListTile(
leading: Icon(
Icons.circle,
color: Colors.black,
size: 10.0,
),
visualDensity: VisualDensity(vertical: -3),
horizontalTitleGap: 1.0,
title: Text('지도 보기'),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyMap()),
);
},
),
SizedBox(
height: 5.0,
),
ListTile(
leading: Icon(
Icons.circle,
color: Colors.black,
size: 10.0,
),
visualDensity: VisualDensity(vertical: -3),
horizontalTitleGap: 1.0,
title: Text('설정'),
onTap: (){},
),
SizedBox(
height: 295.0,
),
],
),
),
body: Center(
child: Column(
children: [
SizedBox(
height: 70.0,
),
CircleAvatar(
radius: 90.0,
backgroundColor: Colors.white,
backgroundImage: AssetImage('images/logoimage.jpg'),
),
SizedBox(
height: 30.0,
),
Text(
'한동 알리미',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 210.0,
),
Text(
'DADAEGEEDEUL',
style: TextStyle(
fontSize: 10.0,
),
),
],
),
),
);
}
}
schedule.dart
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
import 'package:work_a/screens/list_screen.dart';
import 'package:hive_flutter/hive_flutter.dart';
// void main() => runApp(MyApp());
//void main() async {
//// hive initialization
//await Hive.initFlutter();
//Hive.registerAdapter(TodoAdapter());
////await Hive.openBox<Todo>(HiveBoxes.todo);
//}
class schedule extends StatelessWidget {
const schedule({Key? key}) : super(key: key);
static final String title = 'Hive Tutorial';
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue
),
home: MyHomePage(
title: '스케줄',
),
);
}
}
list_screen.dart
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
import 'package:work_a/screens/add_todo_Screen.dart';
import 'package:hive_flutter/hive_flutter.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Todo Hive Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
void dispose() async {
Hive.close();
super.dispose();
//await Hive.openBox<Todo>(HiveBoxes.todo);
//await Hive.openBox<dynamic>('todo_box');
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
title: Text(widget.title),
),
body: ValueListenableBuilder(
valueListenable: Hive.box<Todo>(HiveBoxes.todo).listenable(),
builder: (context, Box<Todo> box, _) {
if (box.values.isEmpty)
return Center(
child: Text("리스트가 비었습니다"),
);
return ListView.builder(
itemCount: box.values.length,
itemBuilder: (context, index) {
Todo? res = box.getAt(index);
return Dismissible(
background: Container(color: Colors.red),
key: UniqueKey(),
onDismissed: (direction) {
res!.delete();
},
child: ListTile(
title: Text(res!.title),
subtitle: Text(res.description),
onTap: () {}),
);
},
);
}),
floatingActionButton: FloatingActionButton(
tooltip: 'Add todo',
child: Icon(Icons.add),
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AddTodoScreen(),
),
),
),
);
}
}
add_todo_screen.dart
import 'package:hive/hive.dart';
import 'package:work_a/boxes.dart';
import 'package:work_a/model/todo.dart';
class AddTodoScreen extends StatefulWidget {
AddTodoScreen({Key? key}) : super(key: key);
#override
_AddTodoScreenState createState() => _AddTodoScreenState();
}
class _AddTodoScreenState extends State<AddTodoScreen> {
//void main() async {
// await Hive.openBox<Todo>(HiveBoxes.todo);
//}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
late String title;
late String description;
validated() {
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
_onFormSubmit();
print("Form Validated");
} else {
print("Form Not Validated");
return;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
title: Text('스케줄 추가'),
),
body: SafeArea(
child: Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
autofocus: true,
initialValue: '',
decoration: InputDecoration(
labelText: '스케줄'
),
onChanged: (value) {
setState(() {
title = value;
});
},
validator: (String? value) {
if (value == null || value.trim().length == 0) {
return "required";
}
return null;
},
),
TextFormField(
initialValue: '',
decoration: const InputDecoration(
labelText: '메모',
),
onChanged: (value) {
setState(() {
description = value;
});
},
validator: (String? value) {
if (value == null || value.trim().length == 0) {
return "required";
}
return null;
},
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary:Color.fromRGBO(31, 39, 76, 1.0),
),
onPressed: () {
validated();
},
child: Text('추가'),
)
],
),
),
),
),
);
}
void _onFormSubmit() {
Box<Todo> contactsBox = Hive.box<Todo>(HiveBoxes.todo);
contactsBox.add(Todo(title: title, description: description));
Navigator.of(context).pop();
}
}
ui_test.dart
import 'package:work_a/screens/add_todo_Screen.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Todo Hive Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(31, 39, 76, 1.0),
centerTitle: true,
title: Text(widget.title),
),
body: Container(
child: ListView.builder(
itemBuilder: (context, index) {
return Dismissible(
background: Container(color: Colors.red),
key: UniqueKey(),
onDismissed: (direction) {},
child: ListTile(
title: Text('Title'),
subtitle: Text('Description'),
onTap: () {}),
);
},
),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add todo',
child: Icon(Icons.add),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AddTodoScreen(),
),
),
),
);
}
}
boxs.dart
class HiveBoxes {
static String todo = 'todo_box';
}
todo.dart
import 'package:hive/hive.dart';
part 'todo.g.dart';
#HiveType(typeId: 0)
class Todo extends HiveObject {
#HiveField(0)
String? id;
#HiveField(1)
String title;
#HiveField(2)
String description;
Todo({required this.title, required this.description});
}
and
todo.g.dart
I'm assuming that you are saving Todo objects in todo_box.
Change this:
Hive.openBox('todo_box')
and this:
Hive.openBox<dynamic>('todo_box')
to this:
Hive.openBox<Todo>('todo_box')

I want to show notification count from my login response json data from a login API in my flutter app

I have successfully got a logged in from the login api then i have got a response of json from here. from response i can fetch some of the data. but cann't fetch the notification array and need to count notification array for my notification icon count . How can i do it ? please help.
The response json format is -
{
"id": 1,
"name": "Mr Admin",
"email": "admin2#gmail.com",
"username": "admin2",
"api_token": "oYfajebhRzlxpMZV8dHI6w5R8CrpgybaGqX2ZaIXkGpumE9hZSgLVVINAgaF",
"user_types_id": null,
"created_at": "2020-01-21 16:21:48",
"updated_at": "2020-10-14 11:31:10",
"deleted_at": null,
"unread_notifications": [
{
"id": "d54ee0cc-054a-4d51-a53b-5f6f658841ae",
"type": "App\\Notifications\\HandSlipStatusNotification",
"notifiable_id": 1,
"notifiable_type": "App\\User",
"data": {
"payment_id": 471,
"generate_payment_id": "10200471",
"message": "Hand Slip Settled.",
"amount": 850
},
"read_at": null,
"created_at": "2020-10-12 15:50:38",
"updated_at": "2020-10-12 15:50:38"
},
{
"id": "aedb7880-4201-4805-b017-62242dfed741",
"type": "App\\Notifications\\HandSlipStatusNotification",
"notifiable_id": 1,
"notifiable_type": "App\\User",
"data": {
"payment_id": 471,
"generate_payment_id": "10200471",
"message": "Hand Slip Disbursed.",
"amount": 850
},
"read_at": null,
"created_at": "2020-10-12 15:50:25",
"updated_at": "2020-10-12 15:50:25"
},
i can show the id , name , email etc but cann't access unread_notifications.
my code -
api_service.dart ->
class LoginResponseModel {
final String token;
final String error;
LoginResponseModel({this.token, this.error});
factory LoginResponseModel.fromJson(Map<String, dynamic> json) {
return LoginResponseModel(
token: json["token"] != null ? json["token"] : "",
error: json["error"] != null ? json["error"] : "",
);
}
}
class LoginRequestModel {
String email;
String password;
String username;
LoginRequestModel({
this.email,
this.password,
this.username,
});
Map<String, dynamic> toJson() {
Map<String, dynamic> map = {
// 'email': email.trim(),
'username': username.trim(),
'password': password.trim(),
};
return map;
}
}
login_model
class LoginResponseModel {
final String token;
final String error;
LoginResponseModel({this.token, this.error});
factory LoginResponseModel.fromJson(Map<String, dynamic> json) {
return LoginResponseModel(
token: json["token"] != null ? json["token"] : "",
error: json["error"] != null ? json["error"] : "",
);
}
}
class LoginRequestModel {
String email;
String password;
String username;
LoginRequestModel({
this.email,
this.password,
this.username,
});
Map<String, dynamic> toJson() {
Map<String, dynamic> map = {
// 'email': email.trim(),
'username': username.trim(),
'password': password.trim(),
};
return map;
}
}
login.dart
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'homepage.dart';
class Login extends StatefulWidget {
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
var allData ;
TextEditingController _userController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
bool _isLoading = false;
// arrange method for api log in
signIn( String username,String password) async {
String url = "my Url";
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Map body = { "username": username, "password": password
};
var notificatiion;
var jsonResponse;
var res = await http.post(url, body: body);
//need to check the api status
if (res.statusCode == 200) {
jsonResponse = json.decode(res.body);
notificatiion = jsonResponse['unread_notifications'];
print("Response status: ${res.statusCode}");
print("Response status: ${res.body}");
if (jsonResponse != null) {
setState(() {
_isLoading = false;
});
sharedPreferences.setString("token", jsonResponse['token']);
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext) =>
HomePage(
email: jsonResponse['email'],
name: jsonResponse['name'],
username : jsonResponse['username'],
notification: notificatiion,
),
),
(Route<dynamic> route) => false);
}
} else {
setState(() {
_isLoading == false;
});
print(" Response status : ${res.body}");
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SingleChildScrollView(
child: Center(
child: Container(
padding: EdgeInsets.fromLTRB(20, 100, 20, 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("Login",
style: TextStyle(fontSize: 32),
),
SizedBox(
height: 30,
),
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Container(
height: 220,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(30),
child: TextField(
controller: _userController,
decoration: InputDecoration(hintText: "username"),
),
),
Padding(
padding: const EdgeInsets.all(30),
child: TextField(
controller: _passwordController,
obscureText: true,
decoration: InputDecoration(hintText: "Password"),
),
),
],
),
),
),
SizedBox(
height: 60,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.lightBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Text("Sign In"),
onPressed: _userController.text == ""||
_passwordController.text == ""
? null
: () {
setState(() {
_isLoading = true ;
});
signIn(_userController.text, _passwordController.text);
},
),
),
SizedBox(
height: 20,
),
FlatButton(
child: Text("Forgot password"),
onPressed: (){
},
),
],
),
),
),
),
),
);
}
}
i want to show all the response value in home page . in a profile and in notification's icon. Help me .
homepage.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'login.dart';
import 'login.dart';
class HomePage extends StatelessWidget {
String email;
String name;
String username;
List<dynamic> notification;
HomePage({this.email, this.name, this.username, this.notification, });
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Cash-Management"),
backgroundColor: Colors.blue,
actions: [
IconButton(icon: Icon(Icons.notifications), onPressed: () {}),
IconButton(
icon: Icon(Icons.exit_to_app),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Login()),
);
}),
],
),
body: ListView(
children: <Widget>[
Container(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
" $email ",
style: TextStyle(fontSize: 16),
),
Text(" $name "),
Text(" $username "),
],
),
),
Container(
height: 300,
child: ListView.builder(
itemCount: notification == null ? 0 : notification.length,
itemBuilder: (context, index){
return ListTile(
title: Text(notification[index] ["id"]),
subtitle: Text(notification[index]["type"]),
);
}),
),
],
),
),
);
}
}

How do calling API in flutter using Dio?

I need to parse JSON to object and use it in my app but I need to do this using dio library, but I'm new to it, can anybody help me how to use it to parse a JSON into an object, also my request need a token with it, my object will lock like this :
import 'dart:convert';
Users usersFromJson(String str) => Users.fromJson(json.decode(str));
String usersToJson(Users data) => json.encode(data.toJson());
class Users {
Users({
this.data,
});
List<Datum> data;
factory Users.fromJson(Map<String, dynamic> json) => Users(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.name,
this.email,
this.phone,
this.status,
this.images,
});
int id;
String name;
String email;
String phone;
String status;
List<Image> images;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
name: json["name"],
email: json["email"],
phone: json["phone"],
status: json["status"],
images: List<Image>.from(json["images"].map((x) => Image.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"email": email,
"phone": phone,
"status": status,
"images": List<dynamic>.from(images.map((x) => x.toJson())),
};
}
class Image {
Image({
this.id,
this.url,
this.isProfileImage,
});
int id;
String url;
int isProfileImage;
factory Image.fromJson(Map<String, dynamic> json) => Image(
id: json["id"],
url: json["url"],
isProfileImage: json["is_profile_image"],
);
Map<String, dynamic> toJson() => {
"id": id,
"url": url,
"is_profile_image": isProfileImage,
};
}
can any one help me step by step doing this using provider and dio please!
Try something like this:
final client = Dio();
Future<_yourClass_> getData() async {
final url = 'your-url';
try {
final response = await client.get(url);
if (response.statusCode == 200) {
return _yourClass_.fromJson(response.data);
} else {
print('${response.statusCode} : ${response.data.toString()}');
throw response.statusCode;
}
} catch (error) {
print(error);
}
}
... _yourClass_ data = await getData();
If you already has a token, you can add it into dio like this :
Dio()..options.headers['authorization'] = 'Bearer $token';
Of course it depends on authorization type. Also if you don't have token already, you need to make request first to obtain a token (similar as shown above) and then get token from response.data.
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ContactListWidget extends StatefulWidget {
const ContactListWidget({Key? key}) : super(key: key);
#override
_ContactListWidgetState createState() => _ContactListWidgetState();
}
class _ContactListWidgetState extends State<ContactListWidget> {
List<dynamic> users = [];
#override
void initState() {
super.initState();
getDio();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: ListView(
children: users.map((e) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 4,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
child: Image.network(e["avatar"]),
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(e["name"],
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
)),
Text(e["title"],maxLines: 1,overflow: TextOverflow.ellipsis,),
Chip(label: Text(e["role"]),),
],
),
),
),
],
),
),
Expanded(
flex: 1,
child: Text(
'\$ ${e["balance"].toString() == "null" ? "0" : e["balance"].toString()}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
],
),
),
);
}).toList(),
),
),
);
}
void getDio() async {
try {
var response = await Dio(BaseOptions(headers: {"Content-Type":
"application/json"}))
.get('https://mock-database-f1298.web.app/api/v1/users');
users = response.data["users"];
setState(() {});
} catch (e) {
print(e);
}
}
}
Sample Image
<img src="https://i.stack.imgur.com/OvIOH.png">
//Here is the best solution for calling login apis and pass the parameters
//in loginApis function
// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:dio/dio.dart';
import 'package:rent_house/screens/Navigation/navBar.dart';
Future<String> loginApis({email, password, context}) async {
// isloading:true;
var apiURL = 'https://denga.r3therapeutsassaic.com/public/api/login';
var formData = FormData.fromMap({
'email': email,
'password': password,
});
//final prefs = await SharedPreferences.getInstance();
Dio dio = Dio();
Response responce;
try {
responce = await dio.post(
apiURL,
data: formData,
);
print("response data " + responce.toString());
if (responce.data['error'] == false) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Navbar()),
);
Fluttertoast.showToast(
msg: "Login Successfull", backgroundColor: Colors.cyan);
} else {
Fluttertoast.showToast(
msg: "Login Failed", backgroundColor: Colors.cyan);
}
} catch (e) {
Fluttertoast.showToast(
msg: "User Already exists", backgroundColor: Colors.cyan);
return 'some thing wrong';
}
return '';
}

returning null user back from function

I am working on Login page with Local db SQL in flutter.
The page isn't creating a SQL table and returning null user, thus showing the snackbar "wrong email".
I have tried to debug but can't find the solution as i am pretty new at this.
This is my sign up page:
class _RegisterState extends State<Register> {
DatabaseHelper db = new DatabaseHelper();
TextEditingController emailController = TextEditingController();
TextEditingController mobileController = TextEditingController();
Future<User> _loginUser(String email,String mobile) async{
User saveUser = User.fromMapObject({
email:"hfah#gmail.com",
mobile:"1432567890"
});
await db.saveUser(saveUser).then((val) async {
if(val == 1){
User user = await db.loginUser(email, mobile);
return user;
}
});
}
final _formKey = GlobalKey<FormState>();
final scaffoldKey = new GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
final bgColor = const Color(0xFF4b0081);
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: bgColor,
key: scaffoldKey,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image(
image: AssetImage("assets/newlogo2.png"),
width: 200,
height: 50,
),
Container(
padding: const EdgeInsets.only(top:20.0, right: 20, left: 20),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: "Mobile No",
labelStyle: TextStyle(color: Colors.white)
),
style: TextStyle(color: Colors.white, fontSize: 20.0),
onChanged: (val) {
setState(() => mob = val);
},
controller: emailController,
),
SizedBox(height: 20.0,),
TextFormField(
validator: (val) => val.isEmpty ? 'Enter an Email' : null,
decoration: InputDecoration(
labelText: "Email ID",
labelStyle: TextStyle(color: Colors.white)
),
style: TextStyle(color: Colors.white, fontSize: 20.0),
onChanged: (val){
setState(() => email = val);
},
controller: mobileController,
),
SizedBox(height: 20.0,),
RaisedButton(
color: Colors.white,
child: Text(
'Register',
style: TextStyle(color: bgColor),
),
onPressed: () async {
User user = await _loginUser(emailController.text, mobileController.text);
if(user != null){
Navigator.of(context).push(MaterialPageRoute<Null>(
builder: (BuildContext context){
return new Home(
user:user,
);
}
));
}else{
scaffoldKey.currentState.showSnackBar(
SnackBar(content: Text("Wrong email"),)
);
}
},
splashColor: Colors.grey,
),
SizedBox(height: 12.0,),
Text(
error,
style: TextStyle(
color: Colors.red,
fontSize: 14.0
),
),
FlatButton(
color: bgColor,
child: Text(
'Back to Sign In',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
onPressed: () async {
setState(() {
//widget.toggleView();
},);
},
),
],
),
),
),
],
),
);
}
This is DatabaseHelper class
class DatabaseHelper{
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
String colemail = 'emial_id';
String tablename = 'User';
String colMobile = 'mobild_no';
Future<Database> get db async{
if(_db != null) return _db;
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async{
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "main.db");
var theDb = await openDatabase(path,version:1,onCreate: _onCreate);
return theDb;
}
void _onCreate(Database db,int version) async{
await db.execute("""
CREATE TABLE User(
user_id INTEGER PRIMARY KEY,
email_id TEXT,
mobile_no TEXT
)""");
print("Table created");
}
Future<int> saveUser(User user) async{
var dbClient = await db;
int res = await dbClient.insert(tablename, user.toMap());
return res;
}
Future<User> loginUser(String email,String mobile) async{
var dbClient = await db;
String sql = "SELECT * FROM User WHERE email_id = '$email' AND
mobile_no = '$mobile' ";
var result = await dbClient.rawQuery(sql);
if(result.length == 0) return null;
return User.fromMapObject(result.first);
}
}
And this is User class
class User{
int _user_id;
String email_id;
String mobile_no;
User(this.email_id,this.mobile_no,this._user_id);
String get emailID => email_id;
String get mobileNO => mobile_no;
int get user_id =>_user_id;
set emailID(String newMail){
this.email_id = newMail;
}
set mobileNO(String newMob){
this.mobile_no = newMob;
}
Map <String,dynamic> toMap(){
return {
'email_id': email_id,
'mobile_no': mobile_no,
'user_id':_user_id
};
}
User.fromMapObject(dynamic map){
this.email_id = map['email_id'];
this.mobile_no = map['mobile_no'];
this._user_id = map['user_id'];
}
}
Please help !!!
In _RegisterState class, I don't see if you instantiated DatabaseHelper db; so db is null and you are trying to invoke saveUser on null instance variable in following code
await db.saveUser(saveUser).then((val) async {
if(val == 1){
User user = await db.loginUser(email, mobile);
return user;
}
});
Replace this
Scaffold.of(context).showSnackBar(SnackBar(content: Text("Wrong email"),));
with
scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Wrong email")));
You just need to instantiate db:
class _RegisterState extends State<Register> {
DatabaseHelper db = new DatabaseHelper();
....
}
For the Snackbar error, replace this code:
else{
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("Wrong email"),)
);
}
with:
else{
globalKey.currentState.showSnackBar(
SnackBar(content: Text("Wrong email"),)
);
}

How do I deal with logins on different devices based on API response in flutter?

I'm confused about how to deal with multiple logins with different devices, and I want to give the function back to the login layout when there are other devices that have just logged in to the same user
Future<EventArticleList> getEventArticleList(String token) async {
BuildContext context;
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer $token"
};
var response = await client.get('$endpoint/', headers: headers);
if (response.statusCode == 200) {
print("Masuk Data");
return EventArticleList.fromJson(
json.decode(response.body),
);
} else if (response.statusCode == 401) {
print("401");
return Navigator.of(context)
.pushNamedAndRemoveUntil(RoutePaths.Login, (_) => false);
} else {
throw Exception("ini Eror apa ?");
}
}
the compilation appears I try to add the navigator back to status.code == 401
NoSuchMethodError: The method 'ancestorStateOfType' was called on null
Try this code
Your main class
import 'package:flutter/material.dart';
import 'package:flutterapitut/view/adddata.dart';
import 'package:flutterapitut/view/dashboard.dart';
import 'package:flutterapitut/view/login.dart';
import 'package:flutterapitut/view/register.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String title='';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter CRUD API',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(title: 'Flutter CRUD API'),
routes: <String,WidgetBuilder>{
'/dashboard' : (BuildContext context) => new Dashboard(title:title),
'/login' : (BuildContext context) => new LoginPage(title:title),
},
);
}
}
Your Database Helper class
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class DatabaseHelper{
String serverUrl = "http://flutterapitutorial.codeforiraq.org/api";
var status ;
var token ;
loginData(String email , String password) async{
String myUrl = "$serverUrl/login1";
final response = await http.post(myUrl,
headers: {
'Accept':'application/json'
},
body: {
"email": "$email",
"password" : "$password"
} ) ;
status = response.body.contains('error');
var data = json.decode(response.body);
if(status){
print('data : ${data["error"]}');
}else{
print('data : ${data["token"]}');
_save(data["token"]);
}
}
_save(String token) async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = token;
prefs.setString(key, value);
}
read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
print('read : $value');
}
}
Your login class
import 'package:flutter/material.dart';
import 'package:flutterapitut/Controllers/databasehelper.dart';
import 'package:flutterapitut/view/dashboard.dart';
import 'package:flutterapitut/view/register.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginPage extends StatefulWidget{
LoginPage({Key key , this.title}) : super(key : key);
final String title;
#override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
if(value != '0'){
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) => new Dashboard(),
)
);
}
}
#override
initState(){
read();
}
DatabaseHelper databaseHelper = new DatabaseHelper();
String msgStatus = '';
final TextEditingController _emailController = new TextEditingController();
final TextEditingController _passwordController = new TextEditingController();
_onPressed(){
setState(() {
if(_emailController.text.trim().toLowerCase().isNotEmpty &&
_passwordController.text.trim().isNotEmpty ){
databaseHelper.loginData(_emailController.text.trim().toLowerCase(),
_passwordController.text.trim()).whenComplete((){
if(databaseHelper.status){
_showDialog();
msgStatus = 'Check email or password';
}else{
Navigator.pushReplacementNamed(context, '/dashboard');
}
});
}
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Login',
home: Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: Container(
child: ListView(
padding: const EdgeInsets.only(top: 62,left: 12.0,right: 12.0,bottom: 12.0),
children: <Widget>[
Container(
height: 50,
child: new TextField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Place your email',
icon: new Icon(Icons.email),
),
),
),
Container(
height: 50,
child: new TextField(
controller: _passwordController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Place your password',
icon: new Icon(Icons.vpn_key),
),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new RaisedButton(
onPressed: _onPressed,
color: Colors.blue,
child: new Text(
'Login',
style: new TextStyle(
color: Colors.white,
backgroundColor: Colors.blue),),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new Text(
'$msgStatus',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new FlatButton(
onPressed: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) => new RegisterPage(),
)
)
,
color: Colors.blue,
child: new Text(
'Register',
style: new TextStyle(
color: Colors.white,
),),
),
),
],
),
),
),
);
}
void _showDialog(){
showDialog(
context:context ,
builder:(BuildContext context){
return AlertDialog(
title: new Text('Failed'),
content: new Text('Check your email or password'),
actions: <Widget>[
new RaisedButton(
child: new Text(
'Close',
),
onPressed: (){
Navigator.of(context).pop();
},
),
],
);
}
);
}
}
Here Dashboard is the class you expected to navigate after successfully login
Want more code visite here I hope this work correctly