Does anybody know how to enable a Flutter ElevatedButton on response status 200.
I have post method for fetching data in sevices.dart
Future<http.Response> postRequest() async {
var data = await formatJsonData() as Map<String, dynamic>;
var body = json.encode(data);
var response = await http.post(
Uri.parse('https://link.com'),
headers: {
'Content-Type': 'application/json',
},
body: body);
if (response.statusCode == 200) {
return response;
} else {
throw Exception('Failed to create processing.');
}
}
There is page where i need to enable button and call method resetVariables()
class FinalPage extends StatefulWidget {
const FinalPage({Key? key}) : super(key: key);
@override
_FinalPageState createState() => _FinalPageState();
}
class _FinalPageState extends State<FinalPage> {
void resetVariables() {
processingName = '';
processingQuantity = null;
linkID = '';
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SLV'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: <Widget>[
ElevatedButton(
onPressed: () {
resetVariables();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const Scanner()),
);
},
child: const Text('Done'))
],
)
],
),
),
);
}
}
What is the best solution to do this?
CodePudding user response:
First you need implement a way to enable or disable the button. That can be done by adding a property
bool enabled = false;
to the State and changing the onPressed
attribute of ElevatedButton
:
onPressed: enabled ? () {
resetVariables();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const Scanner()),
);
} : null,
onPressed
being null
will disable the button.
Now we need a way to access the State from whereever you're using your request method. We need to do two things to achieve this.
We need to change the State to not be private anymore by replacing _FinalPageState
with FinalPageState
everywhere (the underscore makes the state private).
We need to find the State by giving it a GlobalKey
. Create a key somewhere, where it can be accessed from your service, as well as when building your Widget:
final GlobalKey<FinalPageState> finalPageKey = GlobalKey();
When building your final page use that key (if you have multiple FinalPage
widgets be sure to give each one a different key)
FinalPage(finalPageKey);
Now you can use that key to access the State when making your request:
try {
http.Response response = await postRequest();
finalPageKey.currentState?.setState(() {
enabled = true;
});
} catch (e) {
//handle exceptions
}
CodePudding user response:
You could create, a cubit for that post method, and use blocbuilder with build when: parameter awaiting the success state.
Another quick but dirty solution would be to use future builder that has button lookalike (made in simple container) and when post function finishes it returns your elevated button.
Still the cubit solution would be the best approach. Here you can learn more about proper state management and ui rebuild control with blocs and cubits.