I’m using the Get package for accessing variables across dart files.
I’m quite new to flutter and am getting a future value error when I try to change the date variable for a future builder function with http requesting a JSON weburl.
Here’s my code:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'tables.dart';
import 'package:date_range_form_field/date_range_form_field.dart';
import 'package:intl/intl.dart';
import '../helpers/DataProvider.dart';
import 'package:get/get.dart';
class IPOForm extends StatefulWidget {
const IPOForm({Key? key}) : super(key: key);
@override
IPOFormState createState() {
return IPOFormState();
}
}
GlobalKey<FormState> myFormKey = new GlobalKey();
class IPOFormState extends State<IPOForm> {
final _formKey = GlobalKey<FormState>();
final DataProvider _getApi = Get.put(DataProvider());
//print(dateSlug);
late List<Map<String, String>> _apiKeys = _getApi.dummyKeys();
var _dateRange;
var _newApiKey;
var _dateStart;
var _dateEnd;
bool validKey = false;
Future<String> _getStockInfo() async {
String apikey = await _newApiKey;
Map dates = await _dateRange;
String responseJson = "";
print(_dateRange);
DateTime start = dates['start']; //DateTime.parse(dates['start']);
DateTime end = dates['end'];
String startDate = DateFormat('yyyy-MM-dd').format(start);
String endDate = DateFormat('yyyy-MM-dd').format(end);
print('from=' + startDate + '&to=' + endDate);
var url = Uri.parse('https://website.com/api/v1/calendar/ipo?from=' +
startDate +
'&to=' +
endDate +
'&token=' +
apikey);
try {
var response = await http.get(url);
responseJson = response.body.toString();
} on Exception catch (exception) {
print(exception);
} catch (error) {
print(error);
}
return responseJson;
}
Future<String> get stockData {
return _getStockInfo();
}
Future<String> get getStockInfo {
return _getStockInfo();
}
void _submitForm() {
final FormState? form = myFormKey.currentState;
form!.save();
}
@override
void initState() {
print("_dateRange: " + _dateRange.toString());
if (_dateRange == null) {
if (_getApi.ipoDateRange != '') {
_dateRange = _getApi.ipoDateRange;
} else {
_dateRange = _getApi.IPOdefaults;
}
} else {
_getApi.ipoDateRange(_dateRange);
}
print(_dateRange);
try {
_getApi.getKeys().then((keys) {
print(keys.toString());
setState(() {
if (keys.first['key2'] != "") {
_newApiKey = keys.first['key2'];
validKey = true;
} else {
_newApiKey = "keyvalue";
validKey = true;
}
_dateRange = _getApi.ipoDateRange != ''
? _getApi.ipoDateRange
: _getApi.IPOdefaults;
});
});
print('_newApiKey: ' + _newApiKey);
} on Exception catch (exception) {
print(exception);
} catch (error) {
print(error);
}
super.initState();
}
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Form(
key: _formKey,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
DateRangeField(
firstDate: DateTime(2022),
enabled: true,
initialValue: DateTimeRange(
start: _dateRange['start'], //DateTime.now(),
end: _dateRange[
'end']), // DateTime.now().add(const Duration(days: 5))),
decoration: const InputDecoration(
labelText: 'Date Range',
prefixIcon: Icon(Icons.date_range),
hintText: 'Please select a start and end date',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.start.isBefore(DateTime.now())) {
// return 'Please enter a later start date';
}
return null;
},
onSaved: (value) {
//_submitForm();
},
onChanged: (value) {
_submitForm();
},
),;
Container(
child: Column(children: [
if (_dateRange == null)
const Center(child: Text("Select a Date Range")),
if (_dateRange != null)
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: MediaQuery.of(context).size.width - 10,
child: Column(children: <Widget>[
validKey
? FutureBuilder(
future: getStockInfo,
builder: (BuildContext context,
AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
String snapshotDataList =
snapshot.data as String;
return DataTableWidget(
dataList: snapshotDataList,
isStockInfoPage: false,
deviceWidth:
MediaQuery.of(context)
.size
.width);
} else if (snapshot.hasError) {
return Text("Error");
}
return const CircularProgressIndicator();
})
: Text("Invalid API Key")
])))
])),
],
))),
);
}
}
The above widget displays the data in a datatable (another widget, DataTableWidget) with a Future builder of a string returned from a stickinfo function that requests the string data from a ajax http request.
I've had errors with the response json and mostly with the future builder while practicing working on flutter as a beginner. The Future Builder error displayed is somehow an XHR error or a platform error with Future.Value
at the end of the function in the dart filed that opens on the error displayed.
I'm trying to change a variable in another (DataProvider.dart) file when the save button is pressed on the DateTimeRange Widget that allows selection of Date Range on click of the widget.
Also, How can I save the Date Time Range value globally so that when I change Tabs, the DateTimeRange value does't reset. Here's the code for the tab widget that allows me to display different widgets on different tabs. The value of the Text value in IPOWidget gets reset when I change tabs.
home: DefaultTabController(
length: 3,
initialIndex: getApi.tabIndex.toInt(),
child: Builder(builder: (context) {
getApi.bldCTX = context;
return Scaffold(
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(
icon: Icon(Icons.bar_chart_outlined),
text: "Stock Info",
),
Tab(
icon: Icon(Icons.insert_chart_outlined),
text: "IPO",
),
Tab(
icon: Icon(
Icons.show_chart_outlined,
),
text: "Stock News",
),
],
),
title: const Text('Stock Information'),
),
body: const TabBarView(
children: [
Center(child: StockInfoForm()),
Center(child: IPOForm()),
Center(child: NewsPage()),
],
),
);
})),