Skip to content

Modals

A modal spawns a new widget tree, making injecting providers not possible out of the box.

This library offers ProviderScopePortal, which gives access to all the providers that were created in the main widget tree.

Example

In the following example, we created a Builder and used its argument innerContext to inject the provider.

final numberProvider = Provider((context) => 1);
Future<void> showNumberDialog({required BuildContext context}) {
return showDialog(
context: context,
builder: (dialogContext) {
return ProviderScopePortal(
mainContext: context,
child: Builder(
builder: (innerContext) {
final number =
numberProvider.of(innerContext);
return Text('$number');
},
),
);
},
);
}
runApp(
MaterialApp(
home: Scaffold(
body: ProviderScope(
providers: [numberProvider],
child: Builder(
builder: (context) {
return ElevatedButton(
onPressed: () {
showNumberDialog(context: context);
},
child: const Text('show dialog'),
);
},
),
),
),
),
);

Graphical representation

When you show a modal, it is spawned in a new widget tree. Only Navigator is the same ancestor, but other widgets are not accessible. This means the ProviderScope created in the main tree are not accessible in the modal, check the graph below to understand the problem.

Graphical representation of provider scope portal exception

We provide ProviderScopePortal, which requires the mainContext parameter to access the providers created in the main tree.

Graphical representation of provider scope portal