How to get data from Future<dynamic> function Flutter - flutter

I'm getting data with this function:
Future<dynamic> getItem(String endpoint, List<String> pathParams) async {
final uri = buildUri(endpoint, pathParams, {});
final response = await http.get(uri, headers: {
'Authorization': 'Bearer $_ACCESS_TOKEN',
'Content-Type': 'application/json'
});
if (response.statusCode == _UNAUTHORIZED) {
return _refresh(
() => getItem(endpoint, pathParams), () => _redirectToLogin());
}
return response.body;
}
When I try to use the data like this:
List user = [];
void getItem() async {
List tmp = await ac.getItem("/v1/users/:0", [idProfile]);
if (mounted) {
setState(() {
user = tmp;
});
}
}
It sais me: it's not a subtype...
I've tried with List, List, List, Map, Map<String, dynamic>, and nothing works.
What type should I use?

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 can i add headers for authorization and content-type flutter

i have this code for to call api;
how can I add authorization and content-type headers to this?
final url = Uri.parse('https://api.collectapi.com/economy/hisseSenedi');
var counter;
var hisseResult;
Future callHisse() async {
try{
final response = await http.get(url);
if(response.statusCode == 200){
var result = hisselistFromJson(response.body);
if(mounted);
setState(() {
counter = result.data.length;
hisseResult = result;
});
return result;
} else {
print(response.statusCode);
}
} catch(e) {
print(e.toString());
}
}
Thanks for your help
you can do this:
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Authorization': '<Your token>'
};
final response = await http.get(url,headers:requestHeaders);

Converting object to an encodable object failed: Instance of '_File' Flutter

I'm trying to post an image to API.
This is my Post Function :
Future<http.Response> ajoutProduit(
String refProduit,
String nomProduit,
double prixAchatProduit,
double prixVenteProduit,
String descriptionProduit,
File imageProduit) async {
List produits = [];
final response = await http.post(
Uri.parse('http://127.0.0.1:8000/api/produit/'),
headers: <String, String>{'Content-Type': 'multipart/form-data'},
body: jsonEncode(<String, dynamic>{
'refProd': refProduit,
'nomProd': nomProduit,
'prixAchat': prixAchatProduit,
'prixVente': prixVenteProduit,
'descriptionProd': descriptionProduit,
'imageProd': imageProduit,
}),
);
if (response.statusCode == 200) {
return produits = jsonDecode(response.body);
} else {
throw Exception('Erreur base de données!');
}
}
and this is my ImagePicker function :
File uploadimage;
Future<void> chooseImage() async {
final ImagePicker picker = ImagePicker();
var choosedimage = await picker.pickImage(source: ImageSource.gallery);
final File convertimage = await File(choosedimage.path);
setState(() {
uploadimage = convertimage;
});
}
Finally, this is the confirm button :
ElevatedButton(
onPressed: (() {
if (_formKey.currentState.validate()) {
setState(() {
future = ajoutProduit(
refProduit.text,
nomProduit.text,
double.parse(prixAchatProduit.text),
double.parse(prixVenteProduit.text),
descriptionProduit.text,
uploadimage);
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Produit Ajouté')),
);
Navigator.of(context, rootNavigator: true).pop();
}
}), ...
When i press the button i get this error in the debug console :
Error: Converting object to an encodable object failed: Instance of '_File'
I would suggest uploading the file as form you can do something like the following
List<http.MultipartFile> files = [await http.MultipartFile.fromPath('file', file.path)];
http.MultipartRequest request = new http.MultipartRequest("POST", uri);
for (http.MultipartFile file in files) {
request.files.add(file);
}
http.StreamedResponse responseStream = await request.send();
http.Response response = await
http.Response.fromStream(responseStream).timeout(Duration(seconds: timeoutSeconds));

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.

How to send data to server in background in flutter?

When using workmanager: ^0.2.3 I have been able to do some work in the background but I can't send data to the sever using the http package in the background. It simply doesn't happen when it gets to the api call.
This is what I've written in main:
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) async {
switch (task) {
case simpleTaskKey:
await sendUnsentDataToServerIfOffline(inputData);
break;
}
return Future.value(true);
});
}
void sendDetailsAPIFromWorker(
List<Details> detailsToSent, Map<String, dynamic> inputData) async {
List<TDetails> tDetails = [];
detailsToSent.forEach((detail) => tDetails.add(TDetails(
serviceTime: detail.serviceTime,
fromStopTime: detail.fromStopTime,
toStopTime: detail.toStopTime,
submitType: detail.submitType,
status: detail.status,
travelledDistance: 0.0)));
SendDetails sendDetail = SendDetails(
userToken: inputData['token'],
missionId: inputData['service_id'],
details: tDetails);
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Accept': 'application/json'
};
try {
final url = '${inputData['base_url']}$kAPISubmitMissionTransportURL';
try {
final response = await http.post(url,
headers: requestHeaders, body: json.encode(sendDetail.toJson()));
if (json.decode(response.body)['Status'] == 1) {
detailsToSent.forEach((detail) => DBHelper.deleteStopTransportData(
kTransportDetailsTableName,
inputData['service_id'],
detail.serviceDetailId));
List<int> ids = [];
await detailsToSent
.forEach((detail) => ids.add(detail.serviceDetailId));
print('ids to to set send: $ids');
await DBHelper.setDetailSent(
kTransportDetailsTableName, ids, inputData['service_id']);
}
} catch (error) {
}
} catch (error) {
print(error);
}
}