skip to Main Content

I have a parent widget with a list of cases for an agency.

The parent gets the data as a future and passes it to a future builder which is building the list widget.

The floating action button is navigating to a new page to create a new case and save it to the db, when I navigator.pop with parameter I want so reload the parent. But the rebuild does not happen in the parent.

It is working though when pressing a dedicated refresh button.

I can see from the print statement in the update function that it always triggered but rebuild just happens when using the refresh button.

...

class _CasesPageState extends State<CasesPage> {
  IsarHelper db = IsarHelper();
  late Future<List<Case>> cases;

  @override
  void initState() {
    super.initState();
    cases = _getCases();
  }

  Future<List<Case>> _getCases() async {
    return await db.getCases();
  }

  _updateCases() async {
    setState(() {
      print("setState");
      cases = _getCases();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(title: "Cases"),
      drawer: const AppDrawer(),
      body: Padding(
        padding: const EdgeInsets.fromLTRB(4.0, 4.0, 4.0, 0.0),
        child: Column(
          children: [
            Expanded(
                flex: 1,
                child: ElevatedButton(
                  onPressed: () {
                    _updateCases(); // rebuild wihtout problems
                  },
                  child: const Text("refresh"),
                )),
            Expanded(
              flex: 11,
              child: FutureBuilder<List<Case>>(
                  future: cases,
                  builder: (BuildContext context, snapshot) {
                    if (snapshot.hasData) {
                      return CaseList(
                        cases: snapshot.data!,
                      );
                    }
                    return const Text("waiting");
                  }),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final popMsg = await Navigator.pushNamed(
            context,
            NewCasePage.routeName,
          );
          if (popMsg == "new") _updateCases(); // triggers function but does not rebuild
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

The widget for creating new cases does the pop action:

...
Navigator.pop(context, "new");
...

Maybe someone can enlighten me?

2

Answers


  1. Chosen as BEST ANSWER

    Ok solved, I am dropping this here as a warning for other rookie developers.

    Lesson learned: Always await your Database operations and don't expect them to happen instantly or forget to await them.

    The fix was super simple at the end: just add an await so the db operation is done when popping the route.

    ...
    await db.createNewCase(newCase);
    Navigator.pop(context, "new");
    ...
    

  2. Try this things in your _updateCases method.

    _updateCases() async {
        cases = await _getCases();
        setState(() {
          print("setState");
          
        });
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search