Flutter: Api Request is taking too long to process - flutter

I'm trying to make an API request in my flutter application but it takes too much time to process like 15-25 seconds.When i run the same request on Postman its working fine and takes only 200 to 650 ms.I tried using diohttp and http client but result is almost same.Below is my code.
import 'package:http/http.dart' as http;
import 'package:dio_http/dio_http.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
Dio dioRest = Dio(
BaseOptions(
baseUrl: baseURL,
headers: {
HttpHeaders.contentTypeHeader: ContentType.json.value,
},
),
);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MYAPP',
home: Scaffold(
appBar: AppBar(title: Text("Home page")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MaterialButton(
child: Text("Go to my profile"),
color: Theme.of(context).primaryColor,
onPressed: () async{
await getAllContentList();
}),
MaterialButton(
child: Text("Go to Accounts"),
color: Theme.of(context).primaryColor,
onPressed: () async{
await getAllContentListHttp();
}),
],
),
),
),
);
}
Future<List<dynamic>> getAllContentList() async {
try {
print('Api Started');
var result = await dioRest.post(baseURL+'secured/v/getAllContentList', options: Options(
headers: {
'Authorization': 'bearer $token',
'Content-Type': 'application/json',
},
));
print('API result :: $result');
if (result.statusCode == 200) {
print('API result decoded :: ${jsonDecode(result.data)}');
return jsonDecode(result.data);
}
throw DioError(requestOptions: result.requestOptions);
} on DioError catch (error) {
if (error.response!.statusCode! >= 400) {
throw AccessTokenException(message: "Token invalid or expired");
}
var businessError = BusinessError.fromJson(error.response?.data);
throw BusinessException(businessError, statusCode: error.response?.statusCode);
} catch (error) {
throw Error();
}
}
Future<List<dynamic>> getAllContentListHttp() async {
try {
print('Api Started');
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
};
String stUrl = baseURL+'protected/users/getAllActiveStreamList';
final response = await http.post(Uri.parse(baseURL+'secured/v/getAllContentList'), headers: requestHeaders);
print('API result :: $response');
if (response.statusCode == 200) {
print('API result decoded :: ${jsonDecode(response.body)}');
return jsonDecode(response.body);
}
throw AccessTokenException(message: "!!!Sorry");
} on DioError catch (error) {
if (error.response!.statusCode! >= 400) {
throw AccessTokenException(message: "Token invalid or expired");
}
var businessError = BusinessError.fromJson(error.response?.data);
throw BusinessException(businessError, statusCode: error.response?.statusCode);
} catch (error) {
throw Error();
}
}
}
Versions used :
http: ^0.13.5
dio_http: ^5.0.4

Related

Flutter Dio: How To Upload FormData/BulkImages Using A Structured Class/Modal Of REST APIs

My problem is different from a general concept. First checkout my current structure of Flutter App where I have to work without changing the structure.
api_service.dart
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:retrofit/http.dart';
import '/network/interceptor/logging_interceptor.dart';
import '/network/response/general_response.dart';
import 'app_url.dart';
part 'api_service.g.dart';
#RestApi(baseUrl: AppUrl.apiUrl)
abstract class ApiService {
factory ApiService(Dio dio, baseUrl) {
dio.options = BaseOptions(
receiveTimeout: 50000,
connectTimeout: 50000,
followRedirects: false,
validateStatus: (status) { return status! < 500; },
headers: {
'Authorization': 'Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
});
dio.interceptors.add(Logging(dio: dio));
return _ApiService(dio, baseUrl: AppUrl.apiUrl);
}
// APIs EndPoints Request Bodies without Token In Header As It Is Added In LoggingInterceptor
#POST('/login')
Future<GeneralResponse> login(#Body() Map<String, dynamic> body);
#POST('/signup')
Future<GeneralResponse> signup(#Body() Map<String, dynamic> body);
#POST('/json_receive')
Future<GeneralResponse> json_receive(#Body() Map<String, dynamic> body);
#POST('/simple_multipart_receiving')
#MultiPart()
Future<GeneralResponse> simple_multipart_receiving(
#Part(name: 'id') int id,
#Part(name: 'data') String data,
#Part(name: 'images') File image,
);
#POST('/formdata_receiving')
#MultiPart()
Future<GeneralResponse> formdata_receiving(formData);
}
api_url.dart
import '/network/api_service.dart';
import 'package:dio/dio.dart' as dio;
class AppUrl {
static const String apiUrl = 'http://192.168.1.1/demo/api/';
static ApiService apiService = ApiService(dio.Dio(),AppUrl.apiUrl);
}
logging_interceptor.dart
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import '/theme/color.dart';
import '/utility/shared_preference.dart';
import '/utility/top_level_variables.dart';
import '../../dialog/error_dialog.dart';
class Logging extends Interceptor {
String endpoint = "";
final Dio dio;
Logging({
required this.dio,
});
#override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
endpoint = options.path;
options.baseUrl = UserPreferences.baseUrl.isNotEmpty ? UserPreferences.baseUrl : "http://192.168.1.1/demo/api/" ;
if (options.path != '/login' &&
options.path != '/signup') {
options.headers.addEntries([MapEntry("token", UserPreferences.AuthToken)]);
}
if (options.path == '/formdata_receiving' || options.path == '/simple_multipart_receiving') {
options.contentType = 'multipart/form-data';
}
return super.onRequest(options, handler);
}
#override
void onResponse(Response response, ResponseInterceptorHandler handler) {
if (response.data['message'] == 'Invalid Token or Token Expired') {
_tokenExpiredDialog(TopVariables.appNavigationKey.currentContext!);
}
else if (response.data['message'] == 'Invalid API Authorization') {
showErrorDialog(response.data['message']);
}
else if (response.data['error'] == 1) {
showErrorDialog(response.data['message'].toString());
}
return super.onResponse(response, handler);
}
#override
Future<void> onError(DioError err, ErrorInterceptorHandler handler) async {
if (err.response?.statusCode == 200) {
// Everything is Alright
}
else if (err.response?.statusCode == 101) {
Navigator.pop(TopVariables.appNavigationKey.currentContext!);
} else if (err.response?.statusCode == 404) {
showErrorDialog(err.error);
}
else if (err.response?.statusCode == 500) {
showErrorDialog(err.error);
}
else {
showErrorDialog(err.toString());
}
//return super.onError(err, handler);
if (_shouldRetryOnHttpException(err)) {
try {
handler.resolve(await DioHttpRequestRetrier(dio: dio).requestRetry(err.requestOptions).catchError((e) {
handler.next(err);
}));
} catch (e) {
handler.next(err);
}
} else {
handler.next(err);
}
}
bool _shouldRetryOnHttpException(DioError err) {
return err.type == DioErrorType.other && ((err.error is HttpException && err.message.contains('Connection closed before full header was received')));
}
}
_tokenExpiredDialog(BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: false, // User Must Tap Button
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
contentPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
content: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
topLeft: Radius.circular(10.0),
),
color: CustomColor.primary),
child: Text(
'Authentication Expired',
textAlign: TextAlign.center,
style: TextStyle(
color: CustomColor.white,
),
),
),
SizedBox(
height: 10,
),
Container(
padding: const EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0),
child: Text(
'Your Authentication Has Been Expired. Please Login Again.',
textAlign: TextAlign.center,
),
),
],
),
),
actions: <Widget>[
Container(
alignment: Alignment.center,
child: TextButton(
child: const Text(
'Ok',
style: TextStyle(color: CustomColor.white),
),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(CustomColor.primary),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)))),
onPressed: () async {
prefs.clear();
Navigator.of(context).pushNamedAndRemoveUntil('/SignIn', (Route<dynamic> route) => false);
},
),
)
]));
},
);
}
/// Dio Retrier
class DioHttpRequestRetrier {
final Dio dio;
DioHttpRequestRetrier({
required this.dio,
});
Future<Response> requestRetry(RequestOptions requestOptions) async {
return dio.request(
requestOptions.path,
cancelToken: requestOptions.cancelToken,
data: requestOptions.data,
onReceiveProgress: requestOptions.onReceiveProgress,
onSendProgress: requestOptions.onSendProgress,
queryParameters: requestOptions.queryParameters,
options: Options(
contentType: requestOptions.contentType,
headers: requestOptions.headers,
sendTimeout: requestOptions.sendTimeout,
receiveTimeout: requestOptions.receiveTimeout,
extra: requestOptions.extra,
followRedirects: requestOptions.followRedirects,
listFormat: requestOptions.listFormat,
maxRedirects: requestOptions.maxRedirects,
method: requestOptions.method,
receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
requestEncoder: requestOptions.requestEncoder,
responseDecoder: requestOptions.responseDecoder,
responseType: requestOptions.responseType,
validateStatus: requestOptions.validateStatus,
),
);
}
}
Now I am using the below code to call it and submit to REST API.
This Is How I Call It And Working
Map<String,dynamic> reqBody = {
'organisation_id': UserPreferences.OrganizationId,
'id': incomingMap["id"],
'data': incomingMap["data"],
'status': 00,
};
ApiService apiService = ApiService(dio.Dio(), AppUrl.apiUrl);
GeneralResponse response = await apiService.json_receive(reqBody);
This Is How I Call FORMDATA But Not Working, Why
var formData = {
'organisation_id': UserPreferences.OrganizationId,
'id': incomingMap["id"],
'data': incomingMap["data"],
'status': 00,
'files': [
MultipartFile.fromFileSync('./example/upload.txt', filename: 'upload.txt'),
MultipartFile.fromFileSync('./example/upload.txt', filename: 'upload.txt'),
]
};
ApiService apiService = ApiService(dio.Dio(), AppUrl.apiUrl);
GeneralResponse response = await apiService.formdata_receiving(formData);
Problem is solved with adding few lines of codes. Here are they. Use the rest of the code as shared above and replace the last 2 code set with the below one.
api_service.dart
#POST('/formdata_receiving')
#MultiPart()
Future<GeneralResponse> formdata_receiving(#Body() FormData formData);
This Is How I Call FORMDATA
var formData = FormData.fromMap({
'organisation_id': UserPreferences.OrganizationId,
'id': incomingMap["id"],
'data': incomingMap["data"],
'status': 00,
'files': [
MultipartFile.fromFileSync('./example/upload.txt', filename: 'upload.txt'),
MultipartFile.fromFileSync('./example/upload.txt', filename: 'upload.txt'),
]
});
ApiService apiService = ApiService(dio.Dio(), AppUrl.apiUrl);
GeneralResponse response = await apiService.formdata_receiving(formData);
flutter
All is working like a charm now.

Call the request each time I navigate to that certain screen in Flutter

I am fetching the user data through the fetchUser() method on the home screen but when I update the income, it is not updated on the home screen when I navigate back. How can I make the method fetchUser be called each time I navigate to the home screen?
Or what else I can do so I can achieve this?
import 'dart:async';
import 'dart:convert';
import 'package:fin_app/apiservice/variables.dart';
import 'package:month_year_picker/month_year_picker.dart';
// import 'dart:developer';
import 'package:http/http.dart' as http;
import 'package:fin_app/screens/login_screen/components/overview_screen/top_card.dart';
import 'package:flutter/material.dart';
import '../../models/user.dart';
import '../monthly_expense/expense_app_theme.dart';
import 'input_form.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String dropdownValue = list.first;
List userData = [];
#override
void initState() {
super.initState();
fetchUser();
}
Future<User> fetchUser() async {
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
};
final response = await http.get(
Uri.parse('https://10.0.2.2:7014/api/user/me'),
headers: requestHeaders,
);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
// income=jsonDecode(response.body)['income'];
income=jsonDecode(response.body)['profile']['income'];
return User.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
print(response.statusCode.toString());
throw Exception('Failed to load user');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: ExpenseAppTheme.background,
body: Column(
children: [
SizedBox(height: 15),
TopNeuCard(balance: '\ 20,000', expense: '100'),
Expanded(
child: Container(
child: Center(
child: Column(
children: [
Container(
padding: EdgeInsets.only(left: 30.00),
alignment: Alignment.topLeft,
child: DropdownButton<String>(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 100,
style: const TextStyle(
color: Color.fromARGB(255, 44, 121, 244)),
underline: Container(
height: 2,
color: Color.fromARGB(255, 44, 121, 244),
),
onChanged: (String? value) {
// This is called when the user selects an item.
setState(() {
dropdownValue = value!;
});
_fetchData();
},
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
Container(height: 275, child: _buildListView(context))
],
)),
)),
],
),
floatingActionButton: FloatingActionButton(
onPressed: navigate,
backgroundColor: Color.fromARGB(255, 121, 146, 237),
child: const Icon(Icons.add_rounded),
),
);
}
Future<void> _fetchData() async {
var apiUrl2 =
'https://10.0.2.2:7014/api/expense/me/month?month=2022%20$dropdownValue';
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
};
final response = await http.get(
Uri.parse(apiUrl2),
headers: requestHeaders,
);
final data = json.decode(response.body);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
setState(() {
userData = data;
});
} else if (response.statusCode == 404) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No expenses present")));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
print(response.statusCode.toString());
throw Exception('Failed to load expenses');
}
}
Future deletePost(String id) async {
var apiUrl = 'https://10.0.2.2:7014/api/expense/me/$id';
// final res = await http.delete(Uri.parse(apiUrl));
// if (res.statusCode == 200) {
// print("Deleted");
// } else {
// throw "Sorry! Unable to delete this post.";
// }
Map<String, String> requestHeaders = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
};
final response = await http.delete(
Uri.parse(apiUrl),
headers: requestHeaders,
);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("Deleted succesfully")));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
print(response.statusCode.toString());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Expense could not be deleted ")));
throw Exception('Failed to load expenses');
}
}
void navigate() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const FormInput()),
);
}
ListView _buildListView(BuildContext context) {
return ListView.builder(
itemCount: userData.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(userData[index]["category"]),
subtitle: Text(userData[index]["date"]),
leading: IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
setState(() {
deletePost(userData[index]["id"]);
userData.removeAt(index);
});
},
),
trailing: Text(
'-' '\$' + userData[index]["amount"].toString(),
style: TextStyle(
//fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.red,
),
),
onTap: () {},
));
},
);
}
}
Change this:
void navigate() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const FormInput()),
);
}
to this:
void navigate() async {
bool result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const FormInput()),
);
if(result != null && result){
fetchUser();
}
}
then inside FormInput, pop like this:
Navigator.pop(context, true);

Server response only showing circular progress dialog and not API data Flutter

I seriously need assistance. I want to show API data on a listview, but It is not showing, only showing circular progress dialog. My api function is working well as it is printing valid json data on console. When I show and navigate to ResultsPage, It just shows circular progress dialog and not the data. Can you tell me where am I going wrong, why the data is not displaying
Your help will be appreciated.
My API function
Future<List<Autogenerated>?> signInData() async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
try {
Response response = await _dio.post('$_baseUrl/api/gateway',
data: {
"ClientPackageId": "0cdd231a-d7ad-4a68-a934-d373affb5100",
"PlatformId": "ios",
"ClientUserId": "AhmedOmar",
"VinNumber": VINumber
},
options: Options(
headers: {
"Content-Type": "application/json;charset=UTF-8",
"Charset": 'utf-8',
"Authorization": "Bearer $token",
},
));
print("data is here");
print(json.encode(response.data));
print(response.statusCode);
if (response.statusCode == 200) {
print("decoded");
List<Map<String, dynamic>> map = [];
map = List<Map<String, dynamic>>.from(
jsonDecode(json.encode(response.data)));
print(map);
// return List<Autogenerated>.from(
// response.data.map((i) => Autogenerated.fromJson(i)));
// return Autogenerated.fromJson(jsonDecode(json.encode(response.data)));
} else if (response.statusCode == 500) {
// call your refresh token api here and save it in shared preference
print(response.statusCode);
await getToken();
signInData();
} else {
throw Exception('Failed to load data');
}
} catch (e) {
print(e);
}
// return null;
}
Where I want to show the list
class ResultsPage extends StatefulWidget {
const ResultsPage({Key? key}) : super(key: key);
#override
_ResultsPageState createState() => _ResultsPageState();
}
class _ResultsPageState extends State<ResultsPage> {
Future<List<Autogenerated>?>? objectList;
_APIState? api;
#override
void initState() {
super.initState();
objectList = api?.signInData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//centerTitle: true,
),
body: Center(
child: FutureBuilder<List<Autogenerated>?>(
future: objectList,
builder: (context, snapshot) {
if (snapshot.hasData) {
print("snapshot data:");
print(snapshot.hasData);
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: (context, index) {
var title = snapshot.data?[index].category;
// var company = snapshot.data[index]['company_name'];
// var skills = snapshot.data[index]['skills'];
// var description = snapshot.data[index]['description'];
// var positions = snapshot.data[index]['positions'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.green.shade300,
),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(title!),
title: Text(title),
subtitle: Text(
title + '\n' + title,
),
trailing: Text(title),
),
);
},
));
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
),
));
}
}
You need to open the comment and return.
Future<List<Autogenerated>?> signInData() async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
try {
Response response = await _dio.post('$_baseUrl/api/gateway',
data: {
"ClientPackageId": "0cdd231a-d7ad-4a68-a934-d373affb5100",
"PlatformId": "ios",
"ClientUserId": "AhmedOmar",
"VinNumber": VINumber
},
options: Options(
headers: {
"Content-Type": "application/json;charset=UTF-8",
"Charset": 'utf-8',
"Authorization": "Bearer $token",
},
));
print("data is here");
print(json.encode(response.data));
print(response.statusCode);
if (response.statusCode == 200) {
print("decoded");
List<Map<String, dynamic>> map = [];
map = List<Map<String, dynamic>>.from(
jsonDecode(json.encode(response.data)));
print(map);
// return List<Autogenerated>.from(
// response.data.map((i) => Autogenerated.fromJson(i)));
// return Autogenerated.fromJson(jsonDecode(json.encode(response.data)));
} else if (response.statusCode == 500) {
// call your refresh token api here and save it in shared preference
print(response.statusCode);
await getToken();
signInData();
} else {
throw Exception('Failed to load data');
}
} catch (e) {
print(e);
}
// return null;
}```

Flutter BLoC 'Future<String>' is not a subtype of type 'String'

currently I'm trying to fetch data from API in BLoC pattern. But after the call, it's throwing this message. 'Future' is not a subtype of type 'String'
Here is the relevanted codes.
Bloc
Stream<NewsState> mapEventToState(NewsEvent event) async* {
if (event is FetchNews) {
yield event.isFeatured == true
? NewsFeaturedLoading()
: NewsCommonLoading();
try {
print("http req->" + event.isFeatured.toString());
final List<News> newsList =
await _fetchNews(event.isFeatured, userRepository.getToken());
yield event.isFeatured == true
? NewsFeaturedSuccess(newsList: newsList)
: NewsCommonSuccess(newsList: newsList);
} catch (error) {
print(error);
yield event.isFeatured == true
? NewsFeaturedFailure(error: error.toString())
: NewsCommonFailure(error: error.toString());
}
}
}
}
HttpCall
Future<List<News>> _fetchNews(isFeatured, accessToken) async {
print("before httprequest->>" + accessToken);
final http.Response response = await http.post(
Uri.parse(Constant.baseUrl + "/api/news"),
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
"x-access-token": "Bearer " + accessToken,
},
body: {
"isFeatured": isFeatured,
},
);
print("response->>>>" + response.body);
if (response.statusCode == 200) {
print("news-> " + response.body);
var obj = json.decode(response.body);
final data = obj["data"] as List;
return data.map((rawPost) {
return News(
id: rawPost['_id'],
title: rawPost['Title'],
content: rawPost['Description'],
);
}).toList();
} else {
throw Exception(json.decode(response.body));
}
}
View
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
SizedBox(height: 25.0),
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: EdgeInsets.only(left: 19.0),
child: Text("Common news",
style: Constant.newsCommonTextStyle),
),
),
if (state is NewsCommonLoading) CircularProgressIndicator(),
if (state is NewsCommonSuccess) CommonNews(),
if (state is NewsCommonFailure)
Text(state.error, style: TextStyle(color: Colors.red)),
],
),
),
Where does this exception come from? And how can I prevent from this kind of exception? Thank you for your help!
As you mentioned in the comment userRepository.getToken() is an async function so the return value will be Future.
In Dart every function with the async keyword will have the return value of Future<T>.
To obtain the value of a Future and not the Future itself, two methods are provided.
then() - Call this function after the async function to get the value.
await - Add this keyword before and async function to get the value
Update your code to await userRepository.getToken() to get the String value

Null response in await api

This print('response>>>>>>'); print(response); is NULL
print ("api") - this return is OK
In Api.dart
Future list(arguments) async {Dio dio = new Dio();
try {
var arg = arguments;
String refreshToken = token;
dio.options.baseUrl = serverUrl + "/test/" + arg.toString();
dio.options.responseType = ResponseType.json;
Response response = await dio.get(
"${dio.options.baseUrl}",
options: Options(
headers: {
'Authorization': "Bearer $refreshToken",
'Content-Type': "application/json;charset=UTF-8",
'Accept': "gzip"
}
)
);
print ("api");
print(response.data);
return await response.data;
} catch (e) {
print(e);
}
myclass.dart
cl
ass Page extends StatefulWidget {
#override
PageState createState() => PageState();
}
class PageState extends State<Page> {
List data;
Future<List> list() async {
Network network = new Network();
final String arguments = ModalRoute.of(context).settings.arguments as String;
print(arguments);
var response = await network.list(arguments.toString());
print('response>>>>>>');
print(response);
if (mounted){
this.setState(() {
data = response;
});
};
// _saving = false;
// print('data');
// print(data);
// return "Success!";
}
#override
void initState(){
super.initState();
// Future.delayed(Duration.zero, this.dados_propostas);
// dados_propostas();
}
#override
Widget build(BuildContext context) {
this.list();
return AlertDialog(
title: const Text('Teste'),
actions: <Widget>[
FlatButton(
onPressed: debugDumpApp,
child: Row(
children: <Widget>[
const Icon(
Icons.dvr,
size: 18.0,
),
Container(
width: 8.0,
),
const Text('DUMP'),
],
),
),
FlatButton(
onPressed: () {
Navigator.pop(context, false);
},
child: const Text('OK'),
),
],
);
}
}
Use this function:
Future<Response> get(String url, String token) async {
Response response = Response();
try {
dio.options.contentType = "application/json;charset=UTF-8";
dio.options.headers["Authorization"] = "Bearer $token";
response = await dio.get(url);
return response;
} on DioError catch (error, stacktrace) {
print("Exception occured: $error stackTrace: $stacktrace");
return error.response;
}
}