Tentamens
Tentamens

Reputation: 33

Using Navigator in initState

I have a loading screen in which I request some endpoints(API call) and then I want to push to the HomePage

when I call Navigator.push function I get this error:

Unhandled Exception: Navigator operation requested with a context that does not include a Navigator. E/flutter ( 5168): The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.

I have tried wrapping it in WidgetsBinding.instance.addPostFrameCallback((_) as well as added delay of one second before navigating

code snippet:

@override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
   loadData();
});

void loadData() async {
await MyHttpRequests
await Future.delayed(Duration(seconds: 1));
Navigator.pushReplacement(
  context,
  PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) =>
        const HomePage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return child;
    },
    transitionDuration: const Duration(milliseconds: 0),
  ));
}

Upvotes: 0

Views: 142

Answers (1)

Yasir Ali
Yasir Ali

Reputation: 156

Example Solution Wrap your navigation logic in a widget that has access to a Navigator: Ensure that the context you use for navigation is within the widget tree where a Navigator is present.

Use a FutureBuilder to handle the loading state and navigation.

Updated Code Here’s how you can update your initState method and handle navigation correctly:

import 'package:flutter/material.dart';

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      loadData();
    });
  }

  Future<void> loadData() async {
    await MyHttpRequests(); // Replace with your actual HTTP request
    await Future.delayed(Duration(seconds: 1)); // Simulate some delay

    // Ensure the navigation happens in the context of this widget's subtree
    if (mounted) {
      Navigator.pushReplacement(
        context,
        PageRouteBuilder(
          pageBuilder: (context, animation, secondaryAnimation) => HomePage(),
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            return child;
          },
          transitionDuration: const Duration(milliseconds: 0),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CircularProgressIndicator(), // Your loading indicator
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home Page')),
      body: Center(child: Text('Welcome to the Home Page!')),
    );
  }
}

Upvotes: 0

Related Questions