1

I have a screen (ProductAddScreen.dart) that tries to load data from firestore (products unpublished) but if the list is empty, I want to redirect to a new screen (ProductFormScreen.dart).

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Product>>(
      stream: context.watch<ProductService>().unpublished(),
      initialData: [],
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Loading(color: Colors.green);
        }

        // ════════ Exception caught by widgets library ════════
        // setState() or markNeedsBuild() called during build.

        if (!snapshot.hasData) {
          Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ProductFormScreen()));
        }

        return Scaffold(
          appBar: AppBar(
            title: Text(Strings.productAddAppBarTitle),
          ),
          body: ListView.separated(
            itemBuilder: (context, index) {
              final product = snapshot.data[index];
              return ProductItemRow(
                product: snapshot.data[index],
                onTap: () => print('hello'),
              );
            },
            separatorBuilder: (context, index) => Divider(height: 0),
            itemCount: snapshot.data.length,
          ),
        );
      },
    );
  }

I come from react js and I think I am confused. How can I do this with Flutter?

andrefedev
  • 157
  • 2
  • 10

3 Answers3

1

As error states you are trying to navigate during build;

To avoid that could use post build callback:

WidgetsBinding.instance.addPostFrameCallback((_) {
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ProductFormScreen()));
});
Adelina
  • 10,915
  • 1
  • 38
  • 46
  • I just tested and it works as expected. I see it's a bit of a hack .. Could I improve my code to handle this in a better way? – andrefedev Oct 22 '20 at 19:52
  • Could do something similar to this: https://stackoverflow.com/questions/54101589/navigating-to-a-new-screen-when-stream-value-in-bloc-changes – Adelina Oct 22 '20 at 20:04
0
if(snapshot.hasData){
   if(snapshot.data.yourList.length == 0){
       Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => 
       ProductFormScreen()));
   }
   return Scaffold(
       //your design
   );
}

Note :- In your model initialise your List like

List<YourListObject> list = [];
Arpit Awasthi
  • 493
  • 2
  • 8
0
Future navigateToSubPage(context) async {
  Navigator.push(context, MaterialPageRoute(builder: (context) => SubPage()));

Sample code to check the list is empty

return _items.isEmpty ? Center(child: Text('Empty')) : ListView.builder(
  itemCount: _items.length,
  itemBuilder: (context, index) {
    return _buildFilteredItem(context, index);
  },
)
    }
Ashok
  • 3,190
  • 15
  • 31