Home > Enterprise >  How to pass objects based on key from one stateful widget to another stateful widget
How to pass objects based on key from one stateful widget to another stateful widget

Time:03-15

I have this json objects where i specify the menu objects and view objects.

# test.json

{
  "data": {
    "user" : "user1",
    "menu": [
      {
        "label": "Books",
        "view": "books"
      },
      {
        "label": "Author",
        "view": "authors"
      },
      {
        "label": "Publishers",
        "view": "publishers"
      }

    ],
    "view": {
      "books": [
        {
          "block_type": "title",
          "block_data": "Books"
        },
        {
          "block_type": "text",
          "block_data": "This is the view for Books"
        }
      ],
      "authors": [
        {
          "block_type": "title",
          "block_data": "Author"
        },
        {
          "block_type": "text",
          "block_data": "This is the view for Author"
        }
      ],
      "publishers": [
        {
          "block_type": "title",
          "block_data": "Publishers"
        },
        {
          "block_type": "text",
          "block_data": "This is the for Publishers"
        }
      ]
    }
  }
}

I use class called AppContent() with the method getAppContent() to grab the json. I use the menu objects to display the labels inside a drawer menu:

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

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

class _AppMenuState extends State<AppMenu> {
  late Map<String, dynamic> testObject = {};

  setTestData() async {
    await AppContent()
        .getAppContent()
        .then((result) => setState(() => testObject = result));
  }

  @override
  initState() {
    setTestData();
  }

  @override
  Widget build(BuildContext context) {
    return Drawer(
        child: ListView(padding: EdgeInsets.zero, children: [
      DrawerHeader(child: Container()),
      Column(
        children: [
          ListView.builder(
              physics: const NeverScrollableScrollPhysics(),
              shrinkWrap: true,
              itemCount: testObject.containsKey("data")
                  ? (testObject["data"]["menu"] as List<dynamic>).length
                  : 0,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  onTap: () {
                    Navigator.pushAndRemoveUntil(
                      context,
                      MaterialPageRoute(
                        builder: (BuildContext context) => AppView(),
                      ),
                      (route) => false,
                    );
                  },
                  title: Center(
                    child: Column(
                      children: [
                        Text(
                          (testObject["data"]["menu"] as List<dynamic>)[index]
                              ["label"],
                        ),
                      ],
                    ),
                  ),
                );
              }),
        ],
      ),
    ]));
  }
}

Image below views the list of items i show from the json object:

enter image description here

I also have a stateful widget in a seperate file called AppView where i want to show the view objects based on the label that is clicked from the menu.


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

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

class _AppViewState extends State<AppView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      drawer: AppMenu(),
      body: Center(child: Text("AppView")),
    );
  }
}

The AppView is empty because i don't know how to show the view objects from the json object. For example if you click on Books i want to show the objects inside the key ["view"]["books"]. I wonder how i can this?

CodePudding user response:

Good day,

You will need to pass the items corresponding to your selected menu to your AppView. To do so edit your MaterialPageRoute in your _AppMenuState as follows.

...

MaterialPageRoute(
       builder: (BuildContext context) => AppView(selectedMenuItems:  testObject["data"]["view"][testObject["data"]["menu"] as List<dynamic>[index]["view"]]),
    ),

...

Secondly, you will then have to make your AppView accept the parameter (selectedMenuItems) as below.

 class AppView extends StatefulWidget {
  final List selectedMenuItems;

  AppView({Key key, @required this.selectedMenuItems})
      : super(key: key);
  @override
  _AppViewState createState() => _AppViewState();
}

class _AppViewState extends State<AppView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      drawer: AppMenu(),
      body: //Iterate through the selectedMenuItems List
    );
  }
}

That being said, I would recommend you revisit the way you are iterating your testObject inside the ListViewBuilder.

  • Related