How can I use the returned value of data I got from my shared preference json file as a parameter - flutter

how can i use this as my url parameter
userData['UserName']
I have json data in my shared preference file. So I tried to get the username
of the signed in user because I want to use as a parameter to an endpoint.
I can print the username quite ok on the console but when tried to add it
on the link, the statusCode response I get is:
null.
E/flutter ( 906): Receiver: null
E/flutter ( 906): Tried calling: []("UserName")
please how can I extract his username and add it to the endpoint:
Here's the endpoint that shared preference snippet that gives me the
username:
var q;
var userData;
void _getUserInfo() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var userJson = localStorage.getString('loginRes');
user = json.decode(userJson);
setState(() {
userData = user;
});
print(userData['UserName']);
}
and this is where I want to use it, on the get request link below:
Future<void> get_farmer_eop() async {
final response = await http.get(
'http://api.ergagro.com:112/GenerateFarmersEop?farmerBvn=${widget.result}&dcOid=${widget.dc_result}&agentName=${userData['UserName']}',
headers: _setHeaders());
print('${response.statusCode}popo');
if (response.statusCode == 200) {
final jsonStatus = jsonDecode(response.body);
setState(() {
q = jsonStatus['Eop'];
});
print('trandid');
print('${q['TransId']}kukuk');
} else {
throw Exception();
}
}
_setHeaders() => {
'Content-type': 'application/json',
'Accept': 'application/json',
};
But on the console I print the username and if I tried to hardcode the agentName which is the username parameter example agentName=johndoh it works but when userData['UserName'] I keep getting null please can anyone help me?

If _getUserInfo not returning anything then why to create a separate method, try below code. It should work.
Future<void> get_farmer_eop() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var userJson = localStorage.getString('loginRes');
user = json.decode(userJson);
final response = await http.get(
'http://api.ergagro.com:112/GenerateFarmersEop?farmerBvn=${widget.result}&dcOid=${widget.dc_result}&agentName=${user['UserName']}',
headers: _setHeaders());

You are using a wrong formatted url, try this instead:
final response = await http.get(
"http://api.ergagro.com:112/GenerateFarmersEop?farmerBvn=${widget.result}&dcOid=${widget.dc_result}&agentName=${userData['UserName']}",
headers: _setHeaders());

Related

Passing Variable Token Key value in a Flutter Project

I have an api_service.dart file and when the user logs in I save the json.decode(response.body)['key'] in a variable as Tkey. I want to be able to access it in the same file but in a different function when I am trying to access user details:
I am not sure how to apply this answer How to pass access token value in flutter to my code
class APIService {
static var client = http.Client();
static Future<bool> login(
LoginRequestModel model,
) async {
Map<String, String> requestHeaders = {
'Content-Type': 'application/json', };
var url = Uri.parse(
Config.apiURL + Config.loginAPI, );
var response = await client.post(
url,
headers: requestHeaders,
body: jsonEncode(model.toJson()), );
if (response.statusCode == 200) {
await SharedService.setLoginDetails(
loginResponseJson(
response.body, ), );
print("No.2 Test ${response.body}"); <-------{"key":"xxxxxxxxxx"}
var Tkey = json.decode(response.body)['key'];
print("No.2 Test $Tkey"); <-------------- xxxxxxxxxxxxx
return true;
} else {
return false; } }
static Future<User> fetchUser() async {
var url = Uri.parse(Config.apiURL + Config.userProfileAPI);
final response = await http.get(
url,
headers: {
HttpHeaders.authorizationHeader:
'Token $Tkey', <--------------- I want to print here the value of the key
}, );
final responseJson = jsonDecode(response.body);
print(responseJson);
if (response.statusCode == 200) {
return User.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load User');
} }}
My question how can I get access to the key to be used in the fetchUser() ?
Declare a global variable in the global scope or in a separate file, then when this method is executing, assign that key to it, then use it everywhere else in your app.
in a separate file:
String GlobalTkey = "";
now in your method replace the following:
print("No.2 Test ${response.body}"); <-------{"key":"xxxxxxxxxx"}
var Tkey = json.decode(response.body)['key'];
print("No.2 Test $Tkey"); <-------------- xxxxxxxxxxxxx
with this:
print("No.2 Test ${response.body}"); <-------{"key":"xxxxxxxxxx"}
var Tkey = json.decode(response.body)['key'];
GlobalTkey = Tkey; // you need to import the file where the variable exists
print("No.2 Test $Tkey"); <-------------- xxxxxxxxxxxxx
now everywhere in your app including different files, methods, widgets, classes... you can use GlobalTkey

I create flutter with api call but the data not showing at fresh install

So I create an app with rest API, but the data not showing on a fresh install
This is for gettoken and save to shared prefs
getInit() async {
String myUrl = "$serverUrl/get-token";
http.Response response = await http.post(Uri.parse(myUrl),
body: {'secret': 'code'});
debugPrint(response.statusCode.toString());
debugPrint(response.body);
var data = json.decode(response.body)["data"];
_save(data["access_token"]);
// return data;
}
//SAVE TOKEN
_save(String token) async {
final prefs = await SharedPreferences.getInstance();
const key = 'token';
final value = token;
prefs.setString(key, value);
debugPrint("new token save " + value);
}
This for getlist item, need bearer access token from shared prefs
getRecList() async {
final prefs = await SharedPreferences.getInstance();
const key = 'token';
final value = prefs.get(key) ?? 0;
String myUrl = "$serverUrl/home";
http.Response response = await http.get(Uri.parse(myUrl), headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $value'
});
debugPrint(response.body);
if (response.statusCode == 200) {
List data = jsonDecode(response.body)['data'];
List<ModelKost> modelkost =
data.map((item) => ModelKost.fromJson(item)).toList();
return modelkost;
} else {
return <ModelKost>[];
}
}
So every time I fresh install, home page does not show any data because getRecList item is forbidden access...
The log says token success, but getRecList fails because not get access token, it only happens on fresh install if I refresh/hot reload the list showing normally ...
so I guess the function getRecList wrong here, but I have no idea to fix it ...
i think the problem is you are not waiting for token value. use await when geting value from shared preferences
So I create an app with rest API, but the data not showing on a fresh install
getRecList() async {
final prefs = await SharedPreferences.getInstance();
const key = 'token';
final value =await prefs.get(key) ?? 0; //use await here
String myUrl = "$serverUrl/home";
http.Response response = await http.get(Uri.parse(myUrl), headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $value'
});
debugPrint(response.body);
if (response.statusCode == 200) {
List data = jsonDecode(response.body)['data'];
List<ModelKost> modelkost =
data.map((item) => ModelKost.fromJson(item)).toList();
return modelkost;
} else {
return <ModelKost>[];
}
}

Flutter type '_SimpleUri' is not a subtype of type 'String' error

This is my simple code
try{
final dynamic headers = await _getReqHeader();
http.Response res = await http.get(Uri.parse(url), headers: headers);
print("Dres2="+res.toString());
return _result(res);
}catch(e){
print("Dres3="+e.toString());
return _result({});
}
This code works well. But when use some url's I get type '_SimpleUri' is not a subtype of type 'String' error. In postman this url works perfectly. I could not find any information about _SimpleUri. How can I solve this problem?
The get method of the http package takes Uri.https(hostUrl , apiEndpoint) not Uri.parse.
The error appears because a simple URLs being passed to it. To fix this, you have to do this:
http.Response res = await http.get(Uri.https(host, url), headers: headers);
I had a similar issue and that's how I solved it.
static const baseUrl = "apihost.com";
Future<http.Response> _get(String url, {host = baseUrl}) async {
final header = <String, String>{};
return http.get(Uri.https(host, url), headers: header);
}
Future<String?> getData() async {
final response = await _get("/endpoint");
if (isSuccessful(response)) {
final json = jsonDecode(response.body);
} else {
print('GET failed [${response.statusCode}]:
${response.body}');
return null;
}
}

Flutter: What is the Correct approach to get value from Future?

I have a function that which returns user token, and saves it to shared preference, if token is present it saves it to SP. Another method awaits for the token and if token is present authenticates user
Here is my code
login(username, password) async {
final String url = "http://10.0.2.2:8080/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,
}),
);
LoginModel userSave = loginModelFromJson(response.body);
print(response.body);
final SharedPreferences prefs = await SharedPreferences.getInstance();
bool result = await prefs.setString('user', jsonEncode(userSave));
print(result);
}
This piece of code works as expected, but I'm having issue getting the token value from Future.
Case Scenario: User enters username and password and authenticates with server. Incase account exists a token is generated from server and sent to app and stored in shared prefs. token if available is picked from shared prefs and used to login to app, but the check of the token is done before it is generated and saved
Future<LoginModel> getUserInfo() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, dynamic> userMap;
final String userStr = prefs.getString('user');
if (userStr != null) {
userMap = jsonDecode(userStr) as Map<String, dynamic>;
}
if (userMap != null) {
final LoginModel user = LoginModel.fromJson(userMap);
print(user);
return user;
}
return null;
}
the token gets called way before it is saved throwing an error of null
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");
getUserInfo();
// ignore: null_aware_in_condition
if (token == null) {
progressDialog.hide();
showAlertsDialog(context);
// ignore: null_aware_in_condition
} else {
progressDialog.hide();
showAlertzDialog(context);
}
}
},
),
I believe there is very small logical mistake, but unable to find it myself.
I believe you cannot directly call jsonEncode with a custom object like the way you do it in jsonEncode(userSave). Do print(jsonEncode(userSave)); to see if the value is properly being converted into a string.

How to remove quotation and symbols while decoding from JSON value? Flutter

This is the code to get my auth token.
Future <String> getToken() async{
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('token');
}
When i print the token it gives me this json value with double quotation mark.
I/flutter (14710): "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiZDQzZjFjNWZjZDQxYjIzYzllNGU2ZWIyZjQ1M2FmZDgwOTJiNGZmNDAyYjI0OTBmM2RiYTUzMTgzYTU2ODZjNTNiNzVmMDY3ZmIzMmNjMjUiLCJpYXQiOjE1OTA0MDg2NjksIm5iZiI6MTU5MDQwODY2OSwiZXhwIjoxNjIxOTQ0NjY5LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.3YYdR8P1_XzK--VLAwT5gxmkyLZPMuvQhzQQ5OOl_nv0jriPwFY9sqHdL_wiqpAA5vtgBOnyAwZ2kSI_BgDzsKZzY2vMVa47Tyuz87uEFZ7-aHYvNY_r4T_gIkwAuLwc8qN2kuytFjEtuq-iQUiWgEzp5y2n3BDlzXZ7rZi5Xp1_y_6_ysII9RQtX37LuDFt3AIRbYLGDBAilPHi0iJB_jQqWqH8J1mUzCsArj2VuSel7kERqpwFz-SwOOS4EA7CaoOuOlleOpynBalTK9vm1vU3n81K4TAgNq-Mg9CsiFMVQULURdmku7-2gcc3VS8vBXo9OlEgzqmGjLDvIy8_-LCcwuoSVC2DL2t2PIcNUDKQsBu1GBPQ99wzHcnyEpvjVRkg7v4zQWtlIUY6PcLjNf_vnfuXuCERAwBwjS86T7n8ZscfmVVebISVvAKyDN6YhW41hnUw-AZYRLtuhbE8Z48V0tLfLw9aeVr-Qe2mlaYj0LqGYlqBLqUtRl9HSaA9USa6tQ1KQJvF5_6JPcIBJuSkEsrY9n1xhnCViAiyFVF4XWbtToULn69B2UtoXw1X8y_Wek_T7D7t0fi5KWKj8QHO6yI3ZIWViERS2K6n7mnL_3z_7CNeewVxmqMXNdeWl7yPmAMzUAv6z7pWm-R1Qpv7tNVj4-FfQAk3vOm56hE"
This is how i used the token you get the post from api but it isnt working.
Future<Model> ViewWelcomeScreen() async {
String url = '$baseurl/post/20';
ApiService().getToken().then((value){
token = value;
});
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
print(token);
if (response.statusCode == 200) {
var test = json.decode(response.body);
var jsonResponse = test['data'];
return Model.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data');
}
}
Future<Model> ViewWelcomeScreen() async {
String url = '$baseurl/post/20';
ApiService().getToken().then((value){
token = value;
});
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
print(token);
if (response.statusCode == 200) {
var test = json.decode(response.body);
var jsonResponse = test['data'];
return Model.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data');
}
}
code is wrong in a way, think you have async and then both on the same function, why?
ApiService().getToken().then((value){
token = value;
});
here you're saying I want token and I don't need to be awaited then you go and try to use that variable
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
see in flutter every async-await works like event loop in javascript
I write async
normal code
using then in 1. function
dependent code in 1. as async-await
what will be the output?
event loop will be having 1,2,3,4 as async functions
first, it will run 1 and as soon as it receives normal code it runs normally but if it receives then it will understand that this result is not important so let me do rest of the work and will come back to execute 3rd then function so it will run 4 and then 3rd function
but you want token so
ApiService().getToken().then((value){
token = value;
});
replace this to
token = await ApiService().getToken();
your service might need token and that's the reason it's not 200 status code.
If you just want to remove the "" from the string, then just use the replaceAll method
String string = '"foo"';
//Output: 'foo'
string.replaceAll('"', '');

Categories