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

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>[];
}
}

Related

Retrieving data from http web call in flutter into a list object always empty

List is always empty even though body has contents. I am new to flutter so bare with me if this is basic. I am wanting to get back a list of station data I am coming from a c# background so forgive me if am missing something simple the test string body has the items and can see the items when i debug
class HttpService {
final String url = "url hidden";
final String host = 'url hidden';
final String apiSegment = "api/";
// ignore: non_constant_identifier_names
void login(email, password) async {
try {
Map<String, String> body = {
'username': email,
'password': password,
};
Map<String, String> headers = {'Content-Type': 'application/json'};
final msg = jsonEncode(body);
Response response =
await post(Uri.parse("$url/Login"), headers: headers, body: msg);
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data['jwtToken']);
print('Login successfully');
final prefs = await SharedPreferences.getInstance();
await prefs.setString('jwtToken', data['jwtToken']);
List<Stations> stationData = await getStationData('11');
var test = stationData;
} else {
print('failed');
}
} catch (e) {
print(e.toString());
}
}
Future<List<Stations>> getStationData(String stationId) async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('jwtToken');
const String path = 'Station/GetAllStationData';
final uri = Uri.parse('$url/api/$path')
.replace(queryParameters: {'stationId': stationId});
List<Stations> stationData = <Stations>[];
try {
Response res = await get(uri, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token',
});
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
var body2 = body.toString();
stationData = body
.map(
(dynamic item) => Stations.fromJson(item),
)
.toList();
} else {
throw "Unable to retrieve posts.";
}
} catch (e) {
print(e.toString());
}
return stationData;
}
}
I am calling my function from the same class
List<Stations> stationData = await getStationData('11');
Data from body
Actually the problem is you are returning the data after the end of try catch.
Try this
Future<List<Stations>> getStationData(String stationId) async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('jwtToken');
const String path = 'Station/GetAllStationData';
final uri = Uri.parse('$url/api/$path')
.replace(queryParameters: {'stationId': stationId});
try {
Response res = await get(uri, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer $token',
});
if (res.statusCode == 200) {
var body = jsonDecode(res.body);
final stationData = List<Stations>.from(body.map((item) => Stations.fromJson(item))); // made some changes
return stationData;
} else {
throw "Unable to retrieve posts.";
}
} catch (e) {
rethrow;
}
}
I hope this will help you

how to do post request if there is multiple image to be sent with other data

#I am trying to sent my data through rest api all my data seem to be sent accept for my image
static Future<String> postHomework(String classId,String sectionId,String subjectId,String homeWorkTitle,String link,String homeworkDetail, List<XFile> homeworkImage,String submissionDate,BuildContext context) async{
String userData;
String token;
SharedPreferences prefs = await SharedPreferences.getInstance();
userData = prefs.getString("userData");
if(userData!=null){
token = json.decode(userData)['token'];
}else{
return null;
}
http.MultipartRequest request = http.MultipartRequest("POST",Uri.parse("Api goes here"));
Map<String,String> headers = {"Content-Type":"multipart/form-data",'Authorization': 'Bearer $token'};
var bytes = await Future.wait(homeworkImage.map((image) =>image.readAsBytes()));
request.files.addAll(bytes.map((b) =>http.MultipartFile.fromBytes('file', b)));
request.headers.addAll(headers);
request.fields['classid'] = classId;
request.fields['subjectid'] =subjectId;
request.fields['content'] = homeworkDetail;
request.fields['title'] = homeWorkTitle;
request.fields['submission_date'] = submissionDate;
request.fields['section_id'] = sectionId;
http.StreamedResponse responseAttachmentSTR = await request.send();
final reqAttachment = request.files.length;
if(responseAttachmentSTR.statusCode == 200){
print(reqAttachment);
Navigator.of(context).pushNamed("Homework-section-subject-list");
}
print(responseAttachmentSTR.statusCode);
return "SENT";
}
the problem is i am not able to send the images i picked from my gallery to server
Check this out.
I think you have to listen to the response like this :
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});

saved token in login page and how to receive it on List page in flutter?

I have two pages,
Login page
list page
Already saved token in login page, but how to receive it on list page inside Future?
Login page response
Future<Album> createAlbum(String employee_custom_id, String password) async {
final response = await http.post(
Uri.parse('https://portal-api.jomakhata.com/api/auth/login'),
headers: <String, String>{
'Content-Type': 'application/json',
},
body: jsonEncode(<String, String>{
'employee_custom_id': employee_custom_id,
'password': password,
}),
);
final data = json.decode(response.body);
if (response.statusCode == 200) {
saveToken(data);
log('$data');
return Album.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to create album.');
}
}
//save token
void saveToken(data) async{
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("token", data['token']);
sharedPreferences.setInt("userId", data['userId']);
}
Now i want to received it on list page, but can't set it on token section
**List page **
Future<List<ListAlbum>> listData() async {
final token = // I want to receive token here that i saved in login page.
String url =
'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';
Dio dio = new Dio();
dio.options.headers['Content-Type'] = 'application/json';
final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
final response = await dio.post(url, data: body);
}
If I understand correctly you are asking this
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
final token = sharedPreferences.getString("token");
Wouldn't this make sense?
Future<List<ListAlbum>> listData() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
final token = sharedPreferences.getString("token");
String url =
'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';
Dio dio = new Dio();
dio.options.headers['Content-Type'] = 'application/json';
final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
final response = await dio.post(url, data: body);
}

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

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());

How to get the token for register api in flutter

I am having the Url for Token generation,by using http post i am getting the token.now my problem was i have to use the generated token as header in register api(another api).
Future<Map<String, dynamic>> fetchPost() async {
print('feg');
final response = await http.post(
'/rest_api/gettoken&grant_type=client_credentials',
headers: {HttpHeaders.authorizationHeader: "Basic token"},
);
final responseJson = json.decode(response.body);
print("Result: ${response.body}");
//return Post.fromJson(responseJson);
return responseJson;
}
here i am getting the token i want to use that token to register api
Future<Register> fetchPost() async {
print('feg');
final response = await http.post(
'your base url/rest/register/register',
headers: { HttpHeaders.authorizationHeader: "Bearer token",
HttpHeaders.contentTypeHeader: "application/json"},
);
var responseJson = json.decode(response.body);
print("Result: ${response.body}");
return Register.fromJson(responseJson);
}
this is the post method for register api,i want to use previously generated bearer token in above api headers.
Another option, is use secure storage whit Keychain (Android) and Keystore (iOS)
https://pub.dev/packages/flutter_secure_storage
Add in your pubspec.yaml
dependencies:
flutter_secure_storage: ^3.2.1+1
And in your code, import library and save
Future<Map<String, dynamic>> fetchPost() async {
final storage = FlutterSecureStorage();
print('feg');
final response = await http.post(
'/rest_api/gettoken&grant_type=client_credentials',
headers: {HttpHeaders.authorizationHeader: "Basic token"},
);
final responseJson = json.decode(response.body);
print("Result: ${response.body}");
//return Post.fromJson(responseJson);
/// Write token in token key with security
await prefs.write(key: 'token',value: responseJson['token']);
return responseJson;
}
If you need read, use this code:
Future<Register> fetchPost() async {
final storage = FlutterSecureStorage();
print('feg');
String token = await storage.read(key: 'token');
final response = await http.post(
'your base url/rest/register/register',
headers: { HttpHeaders.authorizationHeader: token,
HttpHeaders.contentTypeHeader: "application/json"},
);
var responseJson = json.decode(response.body);
print("Result: ${response.body}");
return Register.fromJson(responseJson);
}
you can save the generated token in the shared preferences. Then you can use it in any request later.
first add in pubspec.yaml
dependencies:
shared_preferences: ^0.5.3+4
then import it in your code:
import 'package:shared_preferences/shared_preferences.dart';
so when you get your token
Future<Map<String, dynamic>> fetchPost() async {
print('feg');
final response = await http.post(
'/rest_api/gettoken&grant_type=client_credentials',
headers: {HttpHeaders.authorizationHeader: "Basic token"},
);
final responseJson = json.decode(response.body);
print("Result: ${response.body}");
//return Post.fromJson(responseJson);
SharedPreferences prefs = await SharedPreferences.getInstance();
//now set the token inside the shared_preferences
//I assumed that the token is a field in the json response, but check it before!!
await prefs.setString('token',responseJson['token']);
return responseJson;
}
and when you need to send the request just get the token from the shared_preferences:
Future<Register> fetchPost() async {
print('feg');
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('token');
final response = await http.post(
'your base url/rest/register/register',
headers: { HttpHeaders.authorizationHeader: token,
HttpHeaders.contentTypeHeader: "application/json"},
);
var responseJson = json.decode(response.body);
print("Result: ${response.body}");
return Register.fromJson(responseJson);
}