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"),)
);
}
Related
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
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"]),
);
}),
),
],
),
),
);
}
}
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 '';
}
I want to upload the image into the API. I tried this code but I got an error
File not found
If I send an image file using Postman, it is working successfully. Here I attached the Postman screenshot, for upload the image I gave the image path and in addition for my document, I want to attach the user id please tell me a solution? thank you
This is my code
class _UserProfileEditState extends State<UserProfileEdit> {
// String imagepath='';
File _profileImage;
String base64Image;
DatabaseHelper databaseHelper = new DatabaseHelper();
int parentid;
_handleimagefromgallary() async {
File imagefile = await ImagePicker.pickImage(source: ImageSource.gallery);
if(imagefile!=null) {
setState(() {
_profileImage = imagefile;
});
}
}
_displayprofilephoto()
{
if(_profileImage==null)
{
if(widget.parentsInfo.data.photo==null)
{
return AssetImage('assets/images/parentimg.png');
}
else
{
return CachedNetworkImageProvider(widget.parentsInfo.data.photo);
}
}
else
{
return FileImage(_profileImage);
}
}
#override
Widget build(BuildContext context) {
parentid=widget.parentsInfo.data.id;
return Scaffold(
appBar: AppBar(
title: Center(
child: Text('Edit Profile'),
),
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height * 1.5,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Container(
height: 160.0,
width: 160.0, //MediaQuery.of(context).size.width,
child: new CircleAvatar(
radius: 50.0,
backgroundColor: Colors.green,
backgroundImage: _displayprofilephoto(),
),
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(''),
InkWell(
child: Icon(Icons.add_photo_alternate),
onTap:_handleimagefromgallary,
),
],
),
),
showpdatebutton(),
This is the method to upload:
Future _updateprofilepicture() async{
// _profileImage=await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
// var path = await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
// var path =await FlutterAbsolutePath.getAbsolutePath(_profileImage.absolute.path);
var path=await FlutterAbsolutePath.getAbsolutePath(_profileImage.path);
if(path==null)
{
}
else
{
// call controller
print(path);
String id=parentid.toString();
databaseHelper.parentprofileupdate(path, id);
// databaseHelper.parentprofileupdate(_profileImage, id);
}
}
Widget showpdatebutton() {
if(_profileImage!=null)
{
return OutlineButton(
child: Text('Update Profile Picture'),
onPressed: (){
_updateprofilepicture();
}
);
}
else
{
return Container();
}
}
}
My database helper class:
Future<ParentProfileUpdate> parentprofileupdate(String path,String id) async
{
Map mapValue;
var data;
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
String myUrl = "$serverUrl/api/v1/upload_parent_image";
await http.post(myUrl,
headers: {
// 'Accept':'application/json',
"HttpHeaders.contentTypeHeader": "application/json",
'Authorization' : 'Bearer $value'
},
body: {
"photo" :path,
"id":id,
}).then((response) {
status = response.body.contains('error');
mapValue=json.decode(response.body);
var data = json.decode(response.body);
print(data);
});
}
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