imharjyotbagga
imharjyotbagga

Reputation: 329

Undefined name 'context' (in Flutter Navigation)

So I was trying to navigate from one screen to another, using Navigator.push (not using NamedRoutes). But suddenly I am getting this error of Undefined name 'context'. I want to navigate from the 'loading_screen.dart' to 'context_screen.dart'. I am not understanding why I am facing this error.

loading_screen.dart

class LoadingScreen extends StatefulWidget {

  String searchTerm;
  LoadingScreen({this.searchTerm});

  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}


class _LoadingScreenState extends State<LoadingScreen> {

  @override
  void initState() {
    print("On Loading Screen");
    String searchTerm = widget.searchTerm;
    getMeaning(searchTerm);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SpinKitWave(
          color: kMainBlueColor,
          size: 70.0,
        ),
      ),
    );
  }
}

void getMeaning(String searchTerm) async {
  print(searchTerm);
  // TODO: get the meaning of the search term.
  // TODO: Test without net and see background loading
  var searchContext;
  // var searchContext = await .....
  Navigator.push(context, MaterialPageRoute(builder: (context) {
    return ContextScreen(searchContext: searchContext);
  }));
}

context_screen.dart

class ContextScreen extends StatefulWidget {

  final searchContext;
  ContextScreen({this.searchContext});

  @override
  _ContextScreenState createState() => _ContextScreenState();
}

class _ContextScreenState extends State<ContextScreen> {
  @override
  Widget build(BuildContext context) {
    var searchContext = widget.searchContext;
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Align(
              alignment: Alignment.topLeft,
              child: FlatButton(
                onPressed: () {
                  int count = 0;
                  Navigator.of(context).popUntil((context) => count++ >= 2);
                },
                child: Icon(
                  Icons.arrow_back_ios,
                  color: kMainBlueColor,
                  size: 50.0,
                ),
              ),
            ),
            Center(
              child: Text(
                searchContext
              ),
            )
          ],
        ),
      )
    );
  }
}

I have neglected the import statements above, but I have added them in my code. Any help would be appreciated. Thanks in advance.

Upvotes: 0

Views: 1844

Answers (2)

chunhunghan
chunhunghan

Reputation: 54365

You can copy paste run full code below
You can move getMeaning into _LoadingScreenState and use addPostFrameCallback

code snippet

class _LoadingScreenState extends State<LoadingScreen> {
  void getMeaning(String searchTerm) async {
    print(searchTerm);
    // TODO: get the meaning of the search term.
    // TODO: Test without net and see background loading
    var searchContext = "";
    // var searchContext = await .....
    await Future.delayed(Duration(seconds: 5), () {
    });

    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return ContextScreen(searchContext: searchContext);
    }));
  }

  @override
  void initState() {
    print("On Loading Screen");
    String searchTerm = widget.searchTerm;

    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      getMeaning(searchTerm);
    });
  }

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';

class LoadingScreen extends StatefulWidget {
  String searchTerm;
  LoadingScreen({this.searchTerm});

  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  void getMeaning(String searchTerm) async {
    print(searchTerm);
    // TODO: get the meaning of the search term.
    // TODO: Test without net and see background loading
    var searchContext = "";
    // var searchContext = await .....
    await Future.delayed(Duration(seconds: 5), () {
    });

    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return ContextScreen(searchContext: searchContext);
    }));
  }

  @override
  void initState() {
    print("On Loading Screen");
    String searchTerm = widget.searchTerm;

    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      getMeaning(searchTerm);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SpinKitWave(
          color: Colors.blue,
          size: 70.0,
        ),
      ),
    );
  }
}

class ContextScreen extends StatefulWidget {
  final searchContext;
  ContextScreen({this.searchContext});

  @override
  _ContextScreenState createState() => _ContextScreenState();
}

class _ContextScreenState extends State<ContextScreen> {
  @override
  Widget build(BuildContext context) {
    var searchContext = widget.searchContext;
    return Scaffold(
        body: SafeArea(
      child: Column(
        children: <Widget>[
          Align(
            alignment: Alignment.topLeft,
            child: FlatButton(
              onPressed: () {
                int count = 0;
                Navigator.of(context).popUntil((context) => count++ >= 2);
              },
              child: Icon(
                Icons.arrow_back_ios,
                color: Colors.blue,
                size: 50.0,
              ),
            ),
          ),
          Center(
            child: Text(searchContext),
          )
        ],
      ),
    ));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: LoadingScreen(searchTerm: "test"),
    );
  }
}

Upvotes: 1

mahesh
mahesh

Reputation: 4763

The error is because you have called a method in initState which is using context.context is only available after completion of initState.

So you can call the method in didChangeDependencies, which is called immediately after initState.

To know more about didChangeDependencies: https://api.flutter.dev/flutter/widgets/State/didChangeDependencies.html

To know more about StatefulWidget lifecycle : https://medium.com/flutter-community/widget-state-buildcontext-inheritedwidget-898d671b7956

Upvotes: 1

Related Questions