This works
Builder(
builder: (context) {
final marketService = Provider.of<MarketService>(context);
final time = Provider.of<GraphState>(context).time;
return StreamProvider<List<Candlestick>>(
builder: (context) => marketService.candles(coinId, time),
initialData: <Candlestick>[],
child: _Graph(),
);
},
),
This does not
StreamProvider<List<Candlestick>>(
builder: (context) => Provider.of<MarketService>(context)
.candles(coinId, Provider.of<GraphState>(context).time),
initialData: <Candlestick>[],
child: _Graph(),
),
flutter: โโโก EXCEPTION CAUGHT BY WIDGETS LIBRARY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
flutter: The following assertion was thrown building Expanded(flex: 1):
flutter: inheritFromWidgetOfExactType(InheritedProvider<MarketService>) or inheritFromElement() was called
flutter: before BuilderStateDelegate<Stream<List<Candlestick>>>.initDelegate() completed.
flutter: When an inherited widget changes, for example if the value of Theme.of() changes, its dependent
flutter: widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor
flutter: or an initDelegate() method, then the rebuilt dependent widget will not reflect the changes in the
flutter: inherited widget.
flutter: Typically references to inherited widgets should occur in widget build() methods. Alternatively,
flutter: initialization based on inherited widgets can be placed in the didChangeDependencies method, which
flutter: is called after initDelegate and whenever the dependencies change thereafter.
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 _DelegateElement.inheritFromElement.<anonymous closure>
package:provider/src/delegate_widget.dart:176
flutter: #1 _DelegateElement.inheritFromElement
package:provider/src/delegate_widget.dart:188
flutter: #2 Element.inheritFromWidgetOfExactType
package:flutter/โฆ/widgets/framework.dart:3431
flutter: #3 Provider.of
package:provider/src/provider.dart:222
flutter: #4 GraphView.build.<anonymous closure>
package:cryptograph/views/graph_view.dart:50
flutter: #5 BuilderStateDelegate.initDelegate
package:provider/src/delegate_widget.dart:244
flutter: #6 _DelegateWidgetState._initDelegate
package:provider/src/delegate_widget.dart:117
flutter: #7 _DelegateWidgetState.initState
package:provider/src/delegate_widget.dart:109
flutter: #8 StatefulElement._firstBuild
package:flutter/โฆ/widgets/framework.dart:4042
flutter: #9 ComponentElement.mount
package:flutter/โฆ/widgets/framework.dart:3911
flutter: #10 Element.inflateWidget
package:flutter/โฆ/widgets/framework.dart:3093
flutter: #11 Element.updateChild
package:flutter/โฆ/widgets/framework.dart:2896
flutter: #12 ComponentElement.performRebuild
package:flutter/โฆ/widgets/framework.dart:3944
flutter: #13 Element.rebuild
package:flutter/โฆ/widgets/framework.dart:3730
flutter: #14 ProxyElement.update
package:flutter/โฆ/widgets/framework.dart:4228
................
Pass listen: false to Provider.of<Foo>(context, listen: false) when inside builder
Is there any way to further abstract this process?
provider voluntarily forces you to type that, to explicitly warn the user that changing MarketService/... will not work.
When would someone change MarketService?
Provider.value with a different value, or that class it a ChangeNotifier
This should be documented in the Provider API, along with a recommendation on what to do if you want your widget to rebuild in case your value changes and you need to pass it inside a Provider's builder.
I consider this to be an oversight as users should be able to access context naiively. As long as the widget is lower in the tree anything named context should work as expected and find parent providers. @rrousselGit closed this issue way too fast.
This is the expected behavior. Why do you think that it's not?
I do not dispute that it's working exactly as you expect it to work. I dispute that it works as a user (ie, me) expects it to work. Resolving this would not improve provider in any technical way, but instead improve the developer experience of using provider.
Resolving this would not improve provider in any technical way, but instead improve the developer experience of using provider.
This exception exists to prevent bugs.
This error typically happens when you're trying to _listen_ to a value in a state where updates aren't handled โ which is most likely a mistake.
This either redirect newcomers to ProxyProvider and similar, or force to explicitly specify listen: false.
Well, I just understood what was happening because I pasted that error on Google and this issue appeared. So maybe the error message could be improved so users will understand better what's happening and how to fix it?
This error comes from Flutter โ I don't have the ability to modify it from provider.
But this is in the scope of lazy loading, which bypasses the Flutter exception. In which case, I'll reimplement the exception myself, with custom error messages.
Oh, OK, I thought you could detect this will happen on an assert and generate a message from there.
Most helpful comment
This error comes from Flutter โ I don't have the ability to modify it from
provider.But this is in the scope of lazy loading, which bypasses the Flutter exception. In which case, I'll reimplement the exception myself, with custom error messages.