Why is my snackbar not displaying — Understanding Flutter’s BuildContext

Mario Gunawan
Flutter Tips
Published in
3 min readOct 12, 2022
This guy needs to be understood

If you are using flutter, chances are you have encountered a problem where you cannot display a snackbar, cannot use navigator, or not being able to show dialog. They all have something in common: they all have BuildContext in their argument. To understand how to solve those errors, you must first learn its root which is BuildContext.

BuildContext is something that every widget has. BuildContext makes the widget aware of its parents and children. This results in a widget being able to use its parents or even ancestor’s functionalities. For example, we can use ScaffoldMessenger.of(context).showSnackbar(…) in any widget that is under the Scaffold widget.

So now, why do this code produces an error?

class AbcApp extends StatelessWidget {
const AbcApp({ super.key });
Widget build(BuildContext context) { // the context object
// declared here does no
// have access to scaffold
return Scaffold(
body: ElevatedButton(
onPressed: () {
// this will fails
ScaffoldMessenger.of(context).showSnackbar(...);
},
child: Text("Show snackbar")
}
);
}
}

it fails because the context that is used cannot find any scaffold above the widget (ScaffoldMessenger needs a Scaffold in the context. The BuildContext that is injected in the build method cannot find any Scaffold above AbcApp, because AbcApp is the one rendering it).

If you try to call Scaffold.of(context) function in a build function that creates a Scaffold, it will returns null, that’s why it fails! Same reason if you are using the Navigator.of(context) in a widget that creates the MaterialApp, the material app is the widget that have Navigator in its context. Both of their context cannot find the widget they are looking for to perform the action. What this means is Scaffold.of(context) needs to be called from a widget that is below the widget that’s creating the scaffold itself. For example, the above code can be edited to:

class ScaffoldApp extends StatelessWidget {
const ScaffoldApp({ super.key });
Widget build(BuildContext context) {
return Scaffold(body: SomeElement());
}
}
class SomeElement extends StatelessWidget {
const SomeElement();
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackbar(...);
},
child: Text("Show snackbar")
}
}
}

There is a way to evade creating a widget that only contains a handful amount of code. The answer is to just add a Builder widget that wraps the widget that wants to access the parent above it.

class ScaffoldApp extends StatelessWidget {
const ScaffoldApp({ super.key });
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (BuildContext context) {
return ElevatedButton(
onPressed: () {
// this will run
ScaffoldMessenger.of(context).showSnackbar(...);
},
child: Text("Show snackbar")
);
}
)
);
}
}

The builder is a hacky way of making a widget able to access their parent’s widget directly. Builder widget is not the only widget that can inject context directly. Other class might also have its own BuildContext injection method like ListView.builder, GridView.builder, LayoutBuilder, etc.

In Summary, to resolve the context problem, you can either create a new widget (stateless / stateful), or use the builder method from those classes.

i spent more than 10 minutes indenting those blocks, so please give a like or a follow to praise my effort

If there’s anything in this article that’s confusing or inconsistent, be sure to hit me up. Thanks for reading

--

--

Mario Gunawan
Flutter Tips

I'm a passionate mobile / web developer. Writing articles about software development, mainly about flutter and react.