before I start, I rarely use Dart or Flutter.
So, I have an application to read data through an API, and I have a class called Service_class.dart where I declared the Endpoint:
Future<ProductModel?> getSingleProductData() async {
ProductModel? result;
try {
var finalcode = "PRD89473320";
final response = await http.get(
Uri.parse(
"http://192.168.1.5/v1/api/product/read_single.php?productcode=$finalcode"),
headers: {
HttpHeaders.contentTypeHeader: "application/json",
},
);
if (response.statusCode == 200) {
final item = json.decode(response.body);
result = ProductModel.fromJson(item);
} else {
print("error");
}
} catch (e) {
log(e.toString());
}
return result;
}
At main.dart I have a Textfield:
TextField(
autofocus: true,
controller: _textController,
focusNode: _textNode,
decoration: InputDecoration(
border: OutlineInputBorder(),
),
),
Loading data (product_class.dart)
class DataClass extends ChangeNotifier {
ProductModel? product;
bool loading = false;
getProductData() async {
loading = true;
product = (await getSingleProductData())!;
loading = false;
notifyListeners();
}
}
Passing data to second screen (secondscreen.dart):
void initState() {
super.initState();
final productModel = Provider.of<DataClass>(context, listen: false);
productModel.getProductData();
}
And I would like to automatically fill out textfield value and send it to the $finalcode in Service_class.dart, then load and display on a second page.
CodePudding user response:
Instead of calling async function in initState you should use FutureBuilder
. Here I pass default value to textfield in initState
and call setState
after view build, by that it would call FutureBuilder
again and call your future function
. I also modify your getSingleProductData
to get initial value. like this:
class MyWidget extends StatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
TextEditingController controller = TextEditingController();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
controller.text = "PRD89473320";
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<ProductModel?>(
future: getSingleProductData(controller.text),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
ProductModel data = snapshot.data!;
return TextField(
autofocus: true,
controller: controller,
decoration: InputDecoration(
border: OutlineInputBorder(),
),
);
}
}
}),
),
);
}
Future<ProductModel?> getSingleProductData(String finalcode) async {
ProductModel? result;
try {
final response = await http.get(
Uri.parse(
"http://192.168.1.5/v1/api/product/read_single.php?productcode=$finalcode"),
headers: {
HttpHeaders.contentTypeHeader: "application/json",
},
);
if (response.statusCode == 200) {
final item = json.decode(response.body);
result = ProductModel.fromJson(item);
} else {
print("error");
}
} catch (e) {
log(e.toString());
}
return result;
}
}
CodePudding user response:
can be done like
void initState() {
super.initState();
final productModel = Provider.of<DataClass>(context, listen: false);
productModel.getProductData().then((value) {
_textController.text = ""; // your data
});
}