How to get content from json with SharedPreferences- Flutter/Dart - flutter

How can I get only content from this json:
{
id: 2,
profileImage: {
id: 1,
fileId: "e8ec429d-1e09-48c9-9ec8-6e61c1177324.jpg",
content: "http://localhost/file/e8ec429d-1e09-48c9-9ec8-6e61c1177324.jpg"
}
}
I want to get him from response after my login request using sharedpreferences:
Future<bool> makeLoginRequest(String email, password) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Map data = {
'email': emailController.text,
'password': passwordController.text
};
var jsonResponse;
var url = 'http://10.0.2.2:80/user/login';
var response = await http.post(url, body: data);
if (response.statusCode == 200) {
_isLoading = false;
jsonResponse = json.decode(response.body);
setState((){
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) => NavBar()),
(Route<dynamic> route) => false);
});
return true;
} else {
return false;
}
}
thanks for any help :)

If you just need the content String you can do something like:
String content = jsonResponse['profileImage']['content'];
However a couple of recommendations, I would separate the parsing logic from the networking logic and in general try to have Model objects to map the models you receive from your services (network/storage) instead of extracting directly its content. For a trivial use case like this it's fine but for more complex scenarios it will allow you to write cleaner and more testable code.

Related

Pass the user id to an http parameter

Good morning, I have a login that returns me the UserID from the server, I store it in an instance of Shared Preferences, and I want to use it as a parameter so that in the main screen, it shows five recent records, also brought from the database.
I attach the code of the login, I emphasize that I was trying to pass some arguments by means of the routes, which are the UserID and the Role of the user, to show him a screen in special.
Future<void> login(email, password) async{
try{
var url = 'serverurl';
var response = await http.post(Uri.parse(url),
body:
{
'Email' : email,
'Password' : password
}).timeout(const Duration(seconds: 30));
var datos = jsonDecode(response.body);
print(datos);
if(response.body != '0'){
guardarDatos(datos['UserID'], datos['Role']);
if('Role' == 'admin'){
Navigator.pushNamed(context, '/AdminPage', arguments: {'UserID':UserId, 'Role': Role});
} else {
Navigator.pushNamed(context, '/UserPage', arguments: {'UserID': UserId, 'Role': Role});
}
} else{
//Cuadro de diálogo que indica que los datos son incorrectos.
showDialog(
context: context,
builder: (BuildContext context) {
return const AlertLogin();
});
print('Usuario Incorrecto');
}
} on TimeoutException catch(e){
print('Tiempo de proceso excedido.');
} on Error {
print('http error.');
}
}
The following, is the code for the main screen, where I plan to pass the user id as a parameter in the URL of the http.get, to get the user records, for example number 1.
//HTTP Request
Future<List<Record>> fetchRecord() async {
//final response = await http.get(Uri.parse('https://e5ac-45-65-15257.ngrok.io/get/fiverecords/1')); Este es estático.
final response = await http
.get(Uri.parse('https://e5ac-45-65-152-57.ngrok.io/get/fiverecords/'));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<dynamic, dynamic>>();
return parsed.map<Record>((json) => Record.fromMap(json)).toList();
} else {
throw Exception('Failed to load records.');
}
}
So in your code for main screen, I am assuming you are asking how to retrieve your arguments passed through named routes. Here's what you need to do:
Define a variable:
final user = ModalRoute.of(context)!.settings.arguments;
You can use this user variable to access the UserID and Email just like this:
print('User Email: ${user.UserID}');
print('User Email: ${user.Role}');
Its like calling a map's value using its key.
So this is how your final code might look like:
Future<List<Record>> fetchRecord() async {
final user = ModalRoute.of(context)!.settings.arguments; // You can use this variable directly in your links
//final response = await http.get(Uri.parse('https://e5ac-45-65-15257.ngrok.io/get/fiverecords/1')); Este es estático.
final response = await http
.get(Uri.parse('https://e5ac-45-65-152-57.ngrok.io/get/fiverecords/'));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<dynamic, dynamic>>();
return parsed.map<Record>((json) => Record.fromMap(json)).toList();
} else {
throw Exception('Failed to load records.');
}
}
Hope that solves your problem. Feel free to clear up any confusions.

Get token auth value to another dart using sharedprefence

how to retrieve token variable from sharedprefence in flutter?
i am very new to implement api for my flutter project because previously I was only told to work on the frontend, i have saved auth token in login and here is my code to store token in sharedprefence
signIn(String email, password) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Map data = {
'email': email,
'password': password
};
var jsonResponse = null;
var response = await http.post(Uri.parse("/api/login"), body: data);
if(response.statusCode == 200) {
jsonResponse = json.decode(response.body);
if(jsonResponse != null) {
setState(() {
_isLoading = false;
});
sharedPreferences.setString("token", jsonResponse['data']['token']['original']['token']);
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => HomePage()), (Route<dynamic> route) => false);
}
}
else {
setState(() {
_isLoading = false;
});
scaffoldMessenger.showSnackBar(SnackBar(content:Text("Mohon cek Email dan Password kembali!", textAlign: TextAlign.center,), backgroundColor: Colors.red,));
}
}
and here is the darts place that I want to call the token for auth in the post method
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:kiriapp/models/angkot.dart';
class AngkotProvider with ChangeNotifier {
late AngkotModel _angkot;
AngkotModel get angkot => _angkot;
set angkot(AngkotModel newAngkot) {
_angkot = newAngkot;
notifyListeners();
}
static Future<AngkotModel?> tambah(
String user_id,
String route_id,
String plat_nomor,
String pajak_tahunan,
String pajak_stnk,
String kir_bulanan) async {
try {
var body = {
'user_id': user_id,
'route_id': route_id,
'plat_nomor': plat_nomor,
'pajak_tahunan': pajak_tahunan,
'pajak_stnk': pajak_stnk,
'kir_bulanan': kir_bulanan,
};
print(body);
var response = await http.post(
Uri.parse('api/create'),
headers: {
'Authorization': 'Bearer $howtocallthetoken?,
},
body: body,
);
print(response.statusCode);
print(response.body);
if (response.statusCode == 201) {
return AngkotModel.fromJson(jsonDecode(response.body));
} else if (response.statusCode == 400) {
return AngkotModel.fromJson(jsonDecode(response.body));
}{
return null;
}
} catch (e) {
print(e);
return null;
}
}
}
thanks
To store something in shared preference we use setString function, just like you did. Now to retrieve it, you should use getString and it will return the token you stored earlier.
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String accessToken = sharedPreferences.getString("token");
var response = await http.post(
Uri.parse('api/create'),
headers: {
'Authorization': 'Bearer $accessToken',
},
body: body,
);
Don't forget to make the function async, and handle null values as the getString function might return token as null if not stored correctly.

Passing token in Flutter from auth to http-request

how to pass the token value from above code to another screen into a http-request as variable.
class AppStarted extends AuthenticationEvent {}
class LoggedIn extends AuthenticationEvent {
final String token;
const LoggedIn({#required this.token});
#override
List<Object> get props => [token];
#override
String toString() => 'LoggedIn { token: $token }';
}
Thank you for your help, haning on this for 2 hours now...
first create a class where your where https request handle & token store
class Network {
var token;
final string base= "/api";
//token get when needed
_getToken() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var user = jsonDecode(localStorage.getString('data'));
token = user['token'];
}
//signup
signUp(data, apiUrl) async {
var fullUrl = baseUrl + apiUrl;
return await http.post(fullUrl,
body: jsonEncode(data), headers: _setHeaders());
}
//login
signIn(apiUrl) async {
var fullUrl = baseUrl + apiUrl;
await _getToken();
return await http.get(fullUrl, headers: _setHeaders());
}
}
in sign up page use this method where you use sign up button on pressed
void _signUp() async {
var data = {
'mobile': mobileController.text,
'password': mobileController.text,
};
var res = await Network().signUp(data, '/register');
var body = json.decode(res.body);
if (body.statusCode == 200) {
SharedPreferences localStorage = await SharedPreferences.getInstance();
localStorage.setString('token', json.encode(body['data']['token']));
localStorage.setString('data', json.encode(body['data']));
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => Home()),
);
} else {
// errorMessage = "as you want to show ";
}
}
in sign up page , use this method same as sign up pages
void signIn() async {
var data = {'mobile': mobile, 'password': password};
var res = await Network().signIn(data, '/login');
var body = json.decode(res.body);
if (res.statusCode == 200) {
SharedPreferences localStorage = await SharedPreferences.getInstance();
localStorage.setString('token', json.encode(body['data']['token']));
localStorage.setString('data', json.encode(body['data']));
Navigator.pushReplacement(
context,
new MaterialPageRoute(builder: (context) => HomePage()),
);
} else if (res.statusCode != 200) {
// mobileError = "These credentials do not match our records.";
}
}
now you can have the token when u signup/singIn and store token in sharedSharedPreferences
whenever you try to acces token just called _getToken() method

Flutter Shared preference Login not working properly

I have created Login Page, User is able to login, but problem is that after I navigate to New screen userId is not getting passed from Shared preference. If i close and re-open app then userId is passed properly. How Can I manage this properly.
Future loginUser(String email, String password) async {
String url = 'https://androidapp.factory2homes.com/api/login';
final response =
await http.post(url, body: {'email': email, 'password': password});
print(response.body);
var result = jsonDecode(response.body);
return result;
}
onPressed: () async {
var email = emailController.text;
var password = passwordController.text;
setState(() {
message = 'Please wait...';
});
var result = await loginUser(email, password);
if(result ['result']== true ){
SharedPreferences _prefs = await SharedPreferences.getInstance();
_prefs.setInt('userId', result['user']['id']);
_prefs.setString('userName', result['user']['name']);
_prefs.setString('userEmail', result['user']['email']);
Navigator.push(context, MaterialPageRoute(builder: (context)=>HomeScreen()));
} else {
print('incorrect password');
}
},
Add await as setInt & setString both use Future which perform operation asynchronously
await _prefs.setInt('userId', result['user']['id']);
await _prefs.setString('userName', result['user']['name']);
await _prefs.setString('userEmail', result['user']['email']);

How to use response after POST Request?

How to use data from response after POST request in Flutter/Dart?
this is my function:
signIn(String email, pass) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Map data = {
'email': email,
'password': pass
};
var jsonResponse = null;
var response = await http.post("http://10.0.2.2:80/user/login", body: data);
if(response.statusCode == 200) {
jsonResponse = json.decode(response.body);
if(jsonResponse != null) {
print(jsonResponse);
setState(() {
_isLoading = true;
});
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => MainPage()), (Route<dynamic> route) => false);
}
}
else {
setState(() {
_isLoading = false;
});
print(response.body);
}
}
after run this function, my jsonResponse returns this data to me:
{id: 1, firstName: admin, lastName: admin, accountName: Kot filemon, email: admin#admin.pl, active: false, activateCode: 0, admin: true, latitude: xxx, longitude: xxx, profileImage: null}
so, how can I use this data(without another request to server) in my app on different screen?
I know how to use this type of data in react, because i'm a frontend developer but i don't have any idea how to use this here.
thanks for any help :)
You can save it to SharedPreferences if all the data in this response are common for all screens.
At this moment you cant store all that jsondata in one SharedPreferenceValue. You need to create one value foreach userdata like this:
signIn(String email, pass) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Map data = {
'email': email,
'password': pass
};
var jsonResponse = null;
var response = await http.post("http://10.0.2.2:80/user/login", body: data);
if(response.statusCode == 200) {
jsonResponse = json.decode(response.body);
if(jsonResponse != null) {
print(jsonResponse);
// this lines save the user data in the sharedpreferenceinstance
await prefs.setString('email',jsonResponse[email]);
await prefs.setString('accountName', jsonResponse[accountName]);
//-----------------now you cant send to another page
// if you need to read the saved data use=>prefs.getInt('email');
setState(() {
_isLoading = true;
});
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => MainPage()), (Route<dynamic> route) => false);
}
}
else {
setState(() {
_isLoading = false;
});
print(response.body);
}
}