Flutter handle future response - flutter

i want to store token value and navigate home page using go router after login. i dont know how to handle json data like display or (retrieve)name and role.. i am newbie for programming.
Help me.thanks in advance.i tried futurebuilder examples it not worked. kindly give simple solution.
Future<Loginuser> fetchLoginuser(String mobile, String password) async {
final response = await http.post(
Uri.parse('https://random.url/api/login'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(
<String, String>{'mobile': mobile, 'password': password}));
if (response.statusCode == 200) {
return Loginuser.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to update album.');
}
}
class Userinfo {
double branchcode;
double role;
double name;
Userinfo({required this.branchcode, required this.role, required this.name});
factory Userinfo.fromJson(Map<String, dynamic> json) {
return Userinfo(
branchcode: json['branchcode'], role: json['role'], name: json['name']);
}
}
class Loginuser {
final String message;
final String messagecode;
final String token;
final Userinfo userinfo;
const Loginuser({
required this.message,
required this.messagecode,
required this.token,
required this.userinfo,
});
factory Loginuser.fromJson(Map<String, dynamic> json) {
return Loginuser(
message: json['message'],
messagecode: json['messagecode'],
token: json['token'],
userinfo: json['userinfo']);
}
}

Use shared_preferences usage is straight forward
here just do this
if (response.statusCode == 200) {
Loginuser _user = Loginuser.fromJson(json.decode(response.body));
final prefs = await SharedPreferences.getInstance();
await prefs.setString('token', user.token);
return user;
} else {
throw Exception('Failed to update album.');
}
And next time you want to check wether user was logged in or not
final prefs = await SharedPreferences.getInstance();
final String? action = prefs.getString('token');
if(token == null){ //not logged in}else{ //logged navigate to dashboard}
///Create a separate helper/manager for shared preferences. This is just an example///

Related

flutter search from API Json

Im trying to make a searchbar that fetch data from mysql , but i have a problem that when i call data fetch function it returns
Instance of '_Future<List>'
this is my code
Future<List<Students>> getStudents(String id) async {
var url = 'http://localhost/getStudents.php';
final response = await http.post(Uri.parse(url), body: {
'id':id,
});
var res = jsonDecode(response.body)['fname'] as List;
if (response.statusCode == 200) {
return res.map((std) => Students.fromJson(std)).toList();
}else {
throw Exception('Failed to load shows');
}
}
my class :
class Students{
final int id;
final String fname;
final String sname;
final String tname;
const Students( {
required this.id,
required this.sname,
required this.tname,
required this.fname,
});
factory Students.fromJson(Map<String, dynamic> json) => Students(
id: json['Id'],
sname: json['secname'],
tname:json['thirdname'] ,
fname: json['firstname'],
);
}
getStudents is a future function and you need to await for it:
List<Students> result = await getStudents('');

How to use shared preferences to save token in flutter?

I want to keep the user token in after the user successfully login in flutter.I am trying to save device token to SharedPreferences so I can use it in other widgets,but error is always : Invalid argument(s) (value): Must not be null . How i can save ID and access token ?
My code :
Future<User> login(String username, String password) async {
await checkInternet();
Map<String, String> headers = {
'Content-type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token'
};
Map<String, String> body = {'username': username, 'password': password};
var response = await http.post(Uri.parse(ApiUtil.AUTH_LOGIN),
headers: headers, body: jsonEncode(body));
switch (response.statusCode) {
case 200:
var body = jsonDecode(response.body);
// print(body);
var data = body['user'];
// print(data);
User user = User.fromJson(data);
await _saveUser(user.id, user.access_token);
return user;
case 404:
throw ResourceNotFound('User');
break;
case 422:
throw UnProcessedEntity();
break;
case 401:
throw LoginFailed();
default:
return null;
break;
}
}
Future<void> _saveUser(int id, String access_token) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setInt('id', id);
sharedPreferences.setString('access_token', access_token);
}
}
and rhis the user model :
class User {
int id;
String name;
String email;
String username;
String phone;
String access_token;
String activeboxe_id;
String adress;
DateTime email_verifed_at;
User(this.name, this.email, this.username, this.phone, this.activeboxe_id,
this.adress, this.email_verifed_at,
[this.access_token, this.id]);
User.fromJson(Map<String, dynamic> jsonObject) {
this.id = jsonObject['id'];
this.name = jsonObject['name'];
this.email = jsonObject['email'];
this.phone = jsonObject['phone'];
this.access_token = jsonObject['access_token'];
this.activeboxe_id = jsonObject['activeboxe_id'];
this.adress = jsonObject['adress'];
this.email_verifed_at = jsonObject['email_verifed_at'];
this.username = jsonObject['username'];
}
}
First check if the values you are trying to save are not null and setInt or setString is an async function so you need to add await before them
Future<void> _saveUser(int id, String access_token) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
await sharedPreferences.setInt('id', id);
await sharedPreferences.setString('access_token', access_token);
}
And your User class is not return the .fromJson if you have noticed
class User {
int id;
String name;
String email;
String username;
String phone;
String access_token;
String activeboxe_id;
String adress;
DateTime email_verifed_at;
User(this.name, this.email, this.username, this.phone, this.activeboxe_id,
this.adress, this.email_verifed_at,
[this.access_token, this.id]);
// return a User object here
factory User.fromJson(Map<String, dynamic> jsonObject) => User({
this.id = jsonObject['id'];
this.name = jsonObject['name'];
this.email = jsonObject['email'];
this.phone = jsonObject['phone'];
this.access_token = jsonObject['access_token'];
this.activeboxe_id = jsonObject['activeboxe_id'];
this.adress = jsonObject['adress'];
this.email_verifed_at = jsonObject['email_verifed_at'];
this.username = jsonObject['username'];
});
}

Unhandled Exception: Converting object to an encodable object failed: Instance of 'LoginModel'

Am still learning and understanding the working of flutter, I am trying to save json string whenever a user logins in for the First time, and use the ID and token to call and interact with different API endpoints. Whenever I try to save the json content to Shared Preference I end with error
Unhandled Exception: Converting object to an encodable object failed:
Instance of 'LoginModel'
My LoginModel
import 'dart:convert';
LoginModel loginModelFromJson(String str) => LoginModel.fromJson(json.decode(str));
String loginModelToJson(LoginModel data) => json.encode(data.toJson());
class LoginModel {
LoginModel({
this.id,
this.username,
this.email,
this.roles,
this.userid,
this.surname,
this.firstname,
this.telephoneno,
this.whatsappno,
this.active,
this.studyrole,
this.tokenType,
this.accessToken,
});
int id;
String username;
String email;
List<String> roles;
String userid;
String surname;
String firstname;
String telephoneno;
String whatsappno;
int active;
String studyrole;
String tokenType;
String accessToken;
factory LoginModel.fromJson(Map<String, dynamic> json) => LoginModel(
id: json["id"],
username: json["username"],
email: json["email"],
roles: List<String>.from(json["roles"].map((x) => x)),
userid: json["userid"],
surname: json["surname"],
firstname: json["firstname"],
telephoneno: json["telephoneno"],
whatsappno: json["whatsappno"],
active: json["active"],
studyrole: json["studyrole"],
tokenType: json["tokenType"],
accessToken: json["accessToken"],
);
Map<String, dynamic> toJson() => {
"id": id,
"username": username,
"email": email,
"roles": List<dynamic>.from(roles.map((x) => x)),
"userid": userid,
"surname": surname,
"firstname": firstname,
"telephoneno": telephoneno,
"whatsappno": whatsappno,
"active": active,
"studyrole": studyrole,
"tokenType": tokenType,
"accessToken": accessToken,
};
}
how am trying to save the Json to shared pref when user clicks on the login button
login(username, password) async {
SharedPref sharedPref = SharedPref();
LoginModel userSave = LoginModel();
final String url = "http://21.76.45.12:80/data/api/auth/signin"; // iOS
final http.Response response = await http.post(
url,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'username': username,
'password': password,
}),
);
print(response.body);
sharedPref.save("user", userSave);
}
My Login button Widget
RoundedButton(
text: "LOGIN",
press: () async {
if (_formKey.currentState.validate()) {
progressDialog.show();
await login(
username,
password,
);
SharedPreferences prefs =
await SharedPreferences.getInstance();
String token = prefs.getString("accessToken");
loadSharedPrefs();
print(token);
// ignore: null_aware_in_condition
if (token == null) {
progressDialog.hide();
showAlertsDialog(context);
// ignore: null_aware_in_condition
} else {
progressDialog.hide();
showAlertzDialog(context);
}
}
},
),
whenever I try to load the preference I get no data
loadSharedPrefs() async {
try {
LoginModel user = LoginModel.fromJson(await sharedPref.read("user"));
Scaffold.of(context).showSnackBar(SnackBar(
content: new Text("Loaded!"),
duration: const Duration(milliseconds: 500)));
setState(() {
userLoad = user;
});
} catch (Excepetion) {
Scaffold.of(context).showSnackBar(SnackBar(
content: new Text("Nothing found!"),
duration: const Duration(milliseconds: 500)));
}
}
My SharedPref class
class SharedPref {
read(String key) async {
final prefs = await SharedPreferences.getInstance();
return json.decode(prefs.getString(key));
}
save(String key, value) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(key, json.encode(value));
}
remove(String key) async {
final prefs = await SharedPreferences.getInstance();
prefs.remove(key);
}
}
what am I doing wrong such that the JSON is not being saved to shared prefs? Thank you for the help
You are not parsing the json anywhere in your code. You are creating an empty object using:
LoginModel userSave = LoginModel();
Which contains null values for the properties and that's why you are getting those exceptions. You want to parse the json and create the object using:
LoginModel userSave = loginModelFromJson(response.body);
sharedPref.save("user", userSave);

adding token with the url string concatenation

hi I want to send token with my api url i tried it by concatenate the token with api url but not. it's showing the error you cannot call the value on null. i cannot figure it out. any help from your side should be appreciate.
This is my api code:
class APIService {
String baseurl = "https://b2all.live/api";
var log = Logger();
FlutterSecureStorage storage = FlutterSecureStorage();
//old get
Future get(String url) async {
await storage.read(key: "api_token");
url = formater(url);
// /user/register
var response = await http.get(
url,
);
if (response.statusCode == 200) {
log.i(response.body);
return json.decode(response.body);
}
log.i(response.body);
log.i(response.statusCode);
}
String formater (String url) {
return baseurl+url;
}
}
And this is my fetching data from api code:
#override
void initState() {
super.initState();
fetchData();
}
void fetchData() async {
var preferences = await SharedPreferences.getInstance();
String api_token = preferences.getString('api_token');
print(api_token);
var response = await networkHandler.get(
"/profile/DvIXUN1CAgYMQzKri0dx3XVxfcABDjbPEg1QyHVD4vu1pQM8pRF56OjLgVW8");
setState(() {
profileModelFix = ProfileModelFix.fromJson(response);
circular = false;
});
}
this is my model file. it's showing error on model. but i cannot figure it out. any help from your side will be helpful for me.
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'profileModelFix.g.dart';
#JsonSerializable()
class ProfileModelFix {
String name;
String user_name;
String dob;
String phone;
String gender;
String bio;
String api_token;
ProfileModelFix ({
this.name, this.user_name, this.dob, this.phone, this.gender, this.bio, this.api_token,
});
factory ProfileModelFix.fromJson(Map<String,dynamic> json) =>
_$ProfileModelFixFromJson(json);
Map<String,dynamic> toJson() => _$ProfileModelFixToJson(this);
}

About Firebase real time database

I am working on Firebase real time databases in Flutter. I am storing user information and their corresponding data in database. My code is given below:
//User Auth Class
class UserAuth{
final String id;
final String email;
final String token;
UserAuth({#required this.id, #required this.email, #required this.token});
}
//User Details Class for storing data of corresponding user
class UserDetails{
final String userDetailsId;
final String name;
final String email;
UserDetails({#required this.userDetailsId,#required this.name, #required this.email});
}
//I am using this code to add userDetails in database.
List<UserDetails> _detailsList = [];
UserDetails _details;
Future<bool> addUserDetails(String username, String email) async {
_isLoading = true;
notifyListeners();
final Map<String, dynamic> userDetails = {
'username': username,
'email': email,
};
try {
final http.Response response = await http.post(
'https://intro-to-firebase-711d4.firebaseio.com/Users.json',
body: json.encode(userDetails));
if (response.statusCode != 200 && response.statusCode != 201) {
_isLoading = false;
notifyListeners();
return false;
}
final Map<String, dynamic> responseData = json.decode(response.body);
_details = UserDetails(
userDetailsId: responseData['name'], name: username, email: email);
_detailsList.add(_details);
_isLoading = false;
notifyListeners();
return true;
} catch (error) {
_isLoading = false;
notifyListeners();
return false;
}
}
Now I want to get the following highlighted ids of the user so how to fetch it. I am using scoped model as a state management in Flutter.
I did it with javascript so far but in the documentation it seems not taht different for flutter:
private void writeNewUser(String userId, String name, String email) {
User user = new User(name, email);
mDatabase.child("users").child(userId).setValue(user);
}
https://firebase.google.com/docs/database/android/read-and-write?authuser=0
This is the example shown in the docs. with .child('users') you can get the right section .child(userId) gives you access to the values.
All you have to do now is defining the variable userId
flutter
you can achieve this as follows
stream: FirebaseDatabase.instance
.reference()
.child('users')
.equalTo(userId)
.onValue,