Home > Back-end >  Passed data returns null flutter
Passed data returns null flutter

Time:12-13

I have a page home_page which uses the BottomNavigationBar For the body i use screens property which contains all the pages based on the current index. I also have a method which i modified for the sake of the question and that passes the number 4000 to the data property. I then want to pass the number 4000 inside data property to the different screens

/*home_page.dart*/

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    getData();
    super.initState();
  }
  static int? data;
  int currentIndex = 0;
  final screens = [
    Child1Page(
      passedData: data
    ),
Child2Page(
      passedData: data,
    ),
Child3Page(
      passedData: data,
    ),
Child4Page(
      passedData: data,
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      body: screens[currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentIndex,
        
        onTap: (index) => setState(() => currentIndex = index),
        items: const [
          BottomNavigationBarItem(
            icon: Icon(
              Icons.home,
              color: Colors.black,
            ),
            label: 'child1',
            backgroundColor: Colors.black,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.add_to_home_screen),
            label: 'child2',
            backgroundColor: Colors.black,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.add_to_home_screen),
            label: 'child3',
            backgroundColor: Colors.black,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.add_to_home_screen),
            label: 'child4',
            backgroundColor: Colors.black,
          ),
        ],
      ),
    );
  }

  Future<void> getData() async {
   
    data = 4000;
  }

  
}
/*child1page.dart*/

class Child1Page extends StatefulWidget {
  final dynamic passedData;
  const Child1Page({Key? key, this.passedData}) : super(key: key);

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

class _Child1PageState extends State<Child1Page> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(widget.passedData),
    );
  }
}

The screens where you can navigate are also in seperate files, one of them for the sake of the question i called child1_page. I am passing the data from the home_page in to child1_page via the screens property. But the problem is that the property passedData is null when i want to acces it in child1_page. For some reason passedData is not invoked with the data inside property data i pass from the method getData and so passedData returns null. My question is how can i pass the data from the method getData to the property data and pass it to the property screens?

CodePudding user response:

I believe the problem comes from the fact that at the time you create the widgets, the data is null. To fix this, you could make the list a getter value:

List<Widget> get screens => [
    Child1Page(
      passedData: data
    ),
Child2Page(
      passedData: data,
    ),
Child3Page(
      passedData: data,
    ),
Child4Page(
      passedData: data,
    ),
  ];

a getter value get's computed every time you call it, it works similar to a function with no parameters, it means that every time you try to read from screens, Child1Page will be redefined with the current value of data. Hopefully it solves the issue.

CodePudding user response:

The issue is coming because of getData(), It is future method, you need to await to fetch data. You can use FutureBuilder to handle this case but calling setState inside FutureBuilder will recall the API again.

While items are const on bottomNavigationBar we can create empty screen list check empty while using on body.

class _AppXState extends State<AppX> {
  static int? data;
  List<Widget> screens = [];
  int currentIndex = 0;

  Future<void> getData() async {
    data = 400; // you may not even using data
    setState(() {
      screens.add(Child1Page(passedData: data));
      //.....
    });
  }

  @override
  void initState() {
    super.initState();
    getData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: screens.isEmpty
          ? const CircularProgressIndicator() //handling watting
          : screens[currentIndex],
  • Related