Issue
I am making a Love Calculator as I am a newbie. But I am fetching the data from the api and calculating it in the backend. But I am not able to do it via button click. Please help me to do so.
import 'dart:io';
import 'package:AllInOneCalci/CustomTextField.dart';
import 'package:AllInOneCalci/Post.dart';
import 'package:AllInOneCalci/customAppBar.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class LoveCalUI extends StatelessWidget {
@override
Widget build(BuildContext context) {
var AppBarHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: customAppBar(
height: (AppBarHeight / 3) * 0.4,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 18.0),
child: Text(
'Love Calculator',
style: TextStyle(
color: Colors.black,
fontSize: 35.0,
fontFamily: 'DancingScript',
fontWeight: FontWeight.bold),
),
),
],
),
),
body: CustomFetchData(),
);
}
}
class CustomFetchData extends StatefulWidget {
@override
_CustomFetchDataState createState() => _CustomFetchDataState();
}
class _CustomFetchDataState extends State<CustomFetchData> {
int percentage = 0;
String result = "";
TextEditingController firstNameController = new TextEditingController();
TextEditingController secondNameController = new TextEditingController();
Future<Post> _getData({String name1, String name2}) async {
final response = await http.get(
'https://love-calculator.p.rapidapi.com/getPercentage?fname=$name1&sname=$name2',
headers: {
'x-rapidapi-host': 'love-calculator.p.rapidapi.com',
'x-rapidapi-key':
'84e84770b9msh59a96d8b03cb4aap1615a1jsn1cd0efaeedfe',
});
if (response.statusCode == 200) {
final responseJson = json.decode(response.body);
setState(() {
percentage = int.parse(responseJson['percentage']);
result = responseJson['result'];
});
} else {
throw Exception('Failed to load api');
}
}
Widget ErrorDesign() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
alignment: Alignment.center,
child: Text(
'Error: Kindly Connect to Internet',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
),
);
}
Widget FetchedCalculationValues() {
return Column(
children: [
Container(
child: FutureBuilder<Post>(
future: _getData(),
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: CircularProgressIndicator(),
),
);
} else {
if (snapshot.hasError) {
return Container(
child: ErrorDesign(),
);
} else {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Text('Percentage is $percentage %',
style: TextStyle(
color: Colors.black,
)),
Text('Result is: $result',
style: TextStyle(
color: Colors.black,
)),
],
),
);
}
}
})),
],
);
}
@override
Widget build(BuildContext context) {
bool visibilitySwitch = false;
return SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 15.0),
child: CustomTextField('First Name', "", Colors.cyan, Colors.cyan,
Colors.redAccent, firstNameController, firstNameController),
),
Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0),
child: CustomTextField(
'Second Name',
"",
Colors.red,
Colors.redAccent,
Colors.cyanAccent,
secondNameController,
secondNameController),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: MaterialButton(
color: Colors.redAccent,
child: Text(
'Result',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
_getData(
name1: firstNameController.text,
name2: secondNameController.text,
);
}),
),
Text(
'Your Score Is: $percentage%',
style: TextStyle(
color: Colors.redAccent,
fontSize: 25.0,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: Text(
'$result',
style: TextStyle(
color: Colors.redAccent,
fontFamily: 'DancingScript',
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
),
],
),
);
}
@override
// ignore: must_call_super
void initState() {
_getData();
}
}
Here I just want to call FetchedCalculationValues() after Result button clicked but I am not able to do so, as the circularProgressIndicator is only loading and not showing the data. The data is displayed but there are some bugs: As by default it is showing 16% and result without entering a single input.
Please help me so that whenever I click the Result button I get a curcularProgressIndicator and then the actual result and whenever I am entering the data it should hide the previous result displayed. Thank You:}
Solution
In onPressed()
, await for the future to complete.
onPressed: () async{
await _getData(
name1:firstNameController.text,
name2:secondNameController.text,
);
}
To show a loading indicator,
Create a function which shows an indicator.
showAlertDialog(BuildContext context){
AlertDialog alert=AlertDialog(
content: new Row(
children: [
CircularProgressIndicator(),
Container(margin: EdgeInsets.only(left: 5),child:Text("Loading" )),
],),
);
showDialog(barrierDismissible: false,
context:context,
builder:(BuildContext context){
return alert;
},
);
}
Now, call it inside onPressed()
onPressed: () async{
showAlertDialog(context);
await _getData(
name1:firstNameController.text,
name2:secondNameController.text);
Navigator.pop(context)//popping the dialog after data is fetched
}
Update
Do that like this,
Create a function which based on a condition returns a Text widget.
bool isLoaded=false;
_getText(){
if(isLoaded){
return Text("your percentage is..$percentage");
}else{
return Container ();// an empty container.
}
}
Now, inside your onPressed
, set isLoaded=true
when you get data from the API.
onPressed: () async{
showAlertDialog(context);
await _getData(
name1:firstNameController.text,
name2:secondNameController.text);
Navigator.pop(context)//popping the dialog after data is fetched
setState((){
isLoaded=true;
});
Answered By - Madhavam
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.