of<T> method

T of <T>(
  1. BuildContext context,
  2. {bool listen: true}
)

Obtains the nearest Provider<T> up its widget tree and returns its value.

If listen is true, later value changes will trigger a new State.build to widgets, and State.didChangeDependencies for StatefulWidget.

listen: false is necessary to be able to call Provider.of inside State.initState or the create method of providers like so:

Provider(
  create: (context) {
    return Model(Provider.of<Something>(context, listen: false)),
  },
)

Implementation

static T of<T>(BuildContext context, {bool listen = true}) {
  assert(
    T != dynamic,
    '''
Tried to call Provider.of<dynamic>. This is likely a mistake and is therefore
unsupported.

If you want to expose a variable that can be anything, consider changing
`dynamic` to `Object` instead.
''',
  );
  assert(
    context.owner.debugBuilding || listen == false || _debugIsInInheritedProviderUpdate,
    '''
Tried to listen to a value exposed with provider, from outside of the widget tree.

This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.

To fix, write:
Provider.of<$T>(context, listen: false);

It is unsupported because may pointlessly rebuild the widget associated to the
event handler, when the widget tree doesn't care about the value.

The context used was: $context
''',
  );

  InheritedContext<T> inheritedElement;

  if (context.widget is _DefaultInheritedProviderScope<T>) {
    // An InheritedProvider<T>'s update tries to obtain a parent provider of
    // the same type.
    context.visitAncestorElements((parent) {
      inheritedElement = parent.getElementForInheritedWidgetOfExactType<_DefaultInheritedProviderScope<T>>()
          as _DefaultInheritedProviderScopeElement<T>;
      return false;
    });
  } else {
    inheritedElement = context.getElementForInheritedWidgetOfExactType<_DefaultInheritedProviderScope<T>>()
        as _DefaultInheritedProviderScopeElement<T>;
  }

  if (inheritedElement == null) {
    throw ProviderNotFoundException(T, context.widget.runtimeType);
  }

  if (listen) {
    context.dependOnInheritedElement(inheritedElement as InheritedElement);
  }

  return inheritedElement.value;
}