I am trying to navigate after login inside futurebuilder. api request done successfully but navigation getting error while testing. Help me How to use futurebuilder properly.
child: ElevatedButton(
onPressed: () {
// Validate returns true if the form is valid, or false otherwise.
if (_mobileKey.currentState!.validate()) {
FutureBuilder<Loginuser>(
future: loginuser(mobileController.text.toString(),
passwordController.text.toString()),
builder: (context, snapshot) {
if (snapshot.hasData) {
context.go('/Home');
return Text(snapshot.data!.message);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
);
}
context.go('/Home');
},
child: const Text('Submit')),
I tried this its not working. I am using " go_router: ^5.2.4 " for navigation
TLDR: Add:
WidgetsBinding.instance.addPostFrameCallback((_) =>
context.go('/Home'));
to the FutureBuilder
I managed to reproduce the problem with this example. Let's take a look.
If you run this code:
import 'package:flutter/material.dart';
void main() => runApp(MainApp());
class MainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: Test()),
);
}
}
class Test extends StatelessWidget {
const Test({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: printHello(),
builder: (context, snapshot) {
if (snapshot.hasData) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage()));
return Text(snapshot.data.toString());
} else if (snapshot.hasError) {
return Text("error");
} else {
return Center(child: CircularProgressIndicator());
}
});
}
}
Future<String> printHello() async {
return Future.value("Hello");
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(body: const Text("home page"));
}
}
You'll see an error:
setState() or markNeedsBuild() called during build.
So, to fix the problem, you need to use WidgetsBinding.instance.addPostFrameCallback:
WidgetsBinding.instance.addPostFrameCallback((_) =>
Navigator.push(context, MaterialPageRoute(builder: (context) {
return HomePage();
})));
but for your example for go_router, add this line:
WidgetsBinding.instance.addPostFrameCallback((_) =>
context.go('/Home'));
Complete working example:
import 'package:flutter/material.dart';
void main() => runApp(MainApp());
class MainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: Test()),
);
}
}
class Test extends StatelessWidget {
const Test({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: printHello(),
builder: (context, snapshot) {
if (snapshot.hasData) {
WidgetsBinding.instance.addPostFrameCallback((_) =>
Navigator.push(context, MaterialPageRoute(builder: (context) {
return HomePage();
})));
return Text(snapshot.data.toString());
} else if (snapshot.hasError) {
return Text("error");
} else {
return Center(child: CircularProgressIndicator());
}
});
}
}
Future<String> printHello() async {
return Future.value("Hello");
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(body: const Text("home page"));
}
}
setState() or markNeedsBuild called during build
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With