skip to Main Content

I’m building multiple (different) UI pages with the same constructor. I’m using a statelful widget as my constructor and in my constractor I get user info data from Firestore. I want to to pass the Firebase data to the different admin UI screens from the constructor.

my constructor

class MyConstructor extends StatefulWidget {
  final navigateToUserPage;
  final String userDetailsString;
  const MyConstructor(
      {super.key,
      required this.navigateToUserPage,
      required this.userDetailsString});

  @override
  State<MyConstructor> createState() => _MyConstructorState();
}

class _MyConstructorState extends State<MyConstructor> {
  QueryDocumentSnapshot<Map<String, dynamic>>? selectedUser;
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream:
          FirebaseFirestore.instance.collection("collectionPath").snapshots(),
      builder: (context, snapshot) {
        return ListView.builder(
          itemCount: snapshot.data!.docs.length,
          itemBuilder: (context, index) {
            final userName = snapshot.data!.docs[index].get("Name");
            return Row(
              children: [
                ListTile(
                  onTap: () {
                    setState(() {
                      selectedUser = userName;
                    });
                  },
                  /*the rest of the code*/
                ),
                TextButton(
                    onPressed: () {
                      Navigator.pushReplacement(
                          context,
                          MaterialPageRoute(
                            builder: (context) => widget.navigateToUserPage(
                                /*what should I pass here*/
                                ),
                          ));
                    },
                    child: Text(widget.userDetailsString)),
              ],
            );
          },
        );
      },
    );
  }
}

class to access the contructor

class MyMainPage extends StatefulWidget {
  const MyMainPage({super.key});

  @override
  State<MyMainPage> createState() => _MyMainPageState();
}

class _MyMainPageState extends State<MyMainPage> {
  @override
  Widget build(BuildContext context) {
    return const MyConstructor(
      navigateToUserPage: UserPage(),
      userDetailsString: "User details",
    );
  }
}

Page to access the data

class UserPage extends StatefulWidget {
  const UserPage({super.key});

  @override
  State<UserPage> createState() => _UserPageState();
}

class _UserPageState extends State<UserPage> {
  /*how do I access the data from previous page*/

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

Any idea on how to pass the data to different pages using this constructor?

2

Answers


  1. Well I should tell you to study 2 things

    1st -> State management -> Provider, bloc, getX etc ( this will tell you how to manage state ) -> This is the most recommended way to handle data/state across your application.

    2nd -> Create a route generator class which will handle all the navigation and with that you can also pass related data to each screen.

    Login or Signup to reply.
  2. Here, You can pass navigationCallback instead of ‘navigateToUserPage’ from the MyMainPage to MyConstructor page like bellow.

    class MyConstructor extends StatefulWidget {
      final Function(Map<String, dynamic> userDetails) navigationCallback;
      final String userDetailsString;
      const MyConstructor(
          {super.key,
          required this.navigationCallback,
          required this.userDetailsString});
    
      @override
      State<MyConstructor> createState() => _MyConstructorState();
    }
    
    class _MyConstructorState extends State<MyConstructor> {
      QueryDocumentSnapshot<Map<String, dynamic>>? selectedUser;
      @override
      Widget build(BuildContext context) {
        return StreamBuilder(
          stream:
              FirebaseFirestore.instance.collection("collectionPath").snapshots(),
          builder: (context, snapshot) {
            return ListView.builder(
              itemCount: snapshot.data!.docs.length,
              itemBuilder: (context, index) {
                final userName = snapshot.data!.docs[index].get("Name");
                return Row(
                  children: [
                    ListTile(
                      onTap: () {
                        setState(() {
                          selectedUser = userName;
                        });
                      },
                      /*the rest of the code*/
                    ),
                    TextButton(
                        onPressed: () {
                          widget.navigationCallback(snapshot.data!.docs[index]);
                        },
                        child: Text(widget.userDetailsString)),
                  ],
                );
              },
            );
          },
        );
      }
    }
    

    Some modifications of MyMainPage will be as bellow:

    class MyMainPage extends StatefulWidget {
      const MyMainPage({super.key});
    
      @override
      State<MyMainPage> createState() => _MyMainPageState();
    }
    
    class _MyMainPageState extends State<MyMainPage> {
      @override
      Widget build(BuildContext context) {
        return MyConstructor(
          navigationCallback: (Map<String, dynamic> userDetails) {
              Navigator.pushReplacement(
                          context,
                          MaterialPageRoute(
                            builder: (context) => UserPage(userDetails: userDetails)));
          },
          userDetailsString: "User details",
        );
      }
    }
    

    UserPage will look like bellow:

    class UserPage extends StatefulWidget {
     UserPage({super.key, required this.userDetails});
    
     Map<String, dynamic> userDetails;
    
      @override
      State<UserPage> createState() => _UserPageState();
    }
    
    class _UserPageState extends State<UserPage> {
      /*how do I access the data from previous page*/
    
      @override
      Widget build(BuildContext context) {
        return const Placeholder();
      }
    }
    

    Note: I have added naming conventions as per your question but you can modify it based on your requirement.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search