0

I have an AppBar button where I want to read a childData list and do something with it:

class _ParentState extends State<Parent> {
....
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          actions: <Widget>[
              IconButton(icon: Icon(Icons.add),
              onPressed: () async {
                    //Need to access childData data here                   
                    print(childData); //currently prints null
                    },
                  ),
              ],
        ),
        body: SafeArea(
          child: Column(
            children: <Widget>[
              ChildWidget(),
            ],

The ChildWidget uses a StreamBuilder and which loops through the snapshots and does something else before appending the snapshot to the list:

class ChildWidgetState extends State<ChildWidget> {
....
Widget build(BuildContext context) {
    return StreamBuilder<List<DocumentSnapshot>>(
        stream: stream,
        builder: (context, snapshots) {
              if (snapshots.connectionState == ConnectionState.active &&
                  snapshots.hasData) {
                      List<DocumentSnapshot> childData = [];
                      for (var x in snapshots.data) {
                          //do something else with snapshot data
                          childData.add(x);
                       }

I have tried to use a callback function where I notify the parent widget to refresh, but this gives a setState() or markNeedsBuild() called during build error as it setStates during the build method of the ChildWidget. I definitely have data within my streambuilder as this is used elsewhere with no issues currently.

A state management package like Provider only seems to provide data to child widgets, not pass them back up, and I've read that using global variables is frowned upon. Would it also be bad practice to add the childData list to a database package like Hive and then read that in my ParentWidget? I don't necessarily want to rebuild the parent widget - just read the data within the child widget when I click my AppBar button.

Thanks.

Luke
  • 37
  • 7

1 Answers1

1

You can use provider to get data in the parent widget

Provider(
  create: (_) => MyModel(),
  child: ParentWidget()
)

on ChildWidget use

data=Provider.of<MyModel>(context);

and MyModel() can be data class containing data you want to get in your parent appBar.

Now in steam builder you can use

data.childData=newData

And after that using

data=Provider.of<MyModel>(context);

In parent widget and

data.childData

Will have newdata you want.

NoobN3rd
  • 1,223
  • 1
  • 9
  • 19
Umer Tariq
  • 94
  • 6