Riverpod 2.0: override with value does not exist anymore - riverpod

I have a provider named gameControllerProvider extends with ChangeNotifier, I initialize it first throw UnimplementedError.
final gameControllerProvider =
ChangeNotifierProvider<GameController>((ref) => throw UnimplementedError());
In my GameBodyWidget I ovverridewith value my gameControlllerProvider
class GameBodyWidget extends ConsumerWidget {
/// {#macro game_body_screen}
const GameBodyWidget({Key? key, required this.gameLevel}) : super(key: key);
final GameLevel gameLevel;
#override
Widget build(BuildContext context, WidgetRef ref) {
return ProviderScope(
overrides: [
gameControllerProvider.overrideWithValue(
GameController()..initializeController(gameLevel, ref),
),
],
child: Stack(
...
),
);
}
As you can see, the reason why I override the controller provider because I need to initialize and pass the parameter of WidgetRef and the GameLevel instance.
Yeah I know I can use the .family method but the problem there is that when I need to call this provider I always pass the parameter
ref.watch(gameControllerProvider('exampleParameter'));

As the changelog says, overrideWithValue is temporarily removed.
But to begin with, in the code you shared, you shouldn't be using it.
Instead do:
ProviderScope(
overrides: [
gameControllerProvider.overrideWithProvider(
ChangeNotifierProvider((ref) {
return GameController()..initializeController(gameLevel, ref),
}),
),
],
)
Using overrideWithValue here is unsafe as a ChangeNotifier is a stateful object. If the widget somehow rebuilt, your ChangeNotifier would be recreated and your state would be lost.
Using overrideWithProvider does not have this issue, as the provider will cache the ChangeNotifier.

For now you can use overrideWithProvider.
This change is temporary, and these methods will be reintroduced in a later version.

Related

returning lists in one dart file to another dart file

I am using lists to create inkwell buttons. I want to put the lists in a separate dart file and import the file into the files where I use the lists. I don't know how to import the lists.
https://pastebin.com/mf0kvsGu
I made a dart file to put the lists into.
https://prnt.sc/ndu736 "Lists error"
void _loginPressed() {
// these handlers are called whenever the user tries to login, resend password or create an account
print('The use wants to login with $_email and $_password');
//if (_email == ""&& _password == "") {
ButtonsLists();
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => BrowsePage(buttonList)));
//}
}
class BuyItem extends StatelessWidget {
BuyItem(this.name, this.image);
final String name;
final String image;
#override
Widget build(BuildContext context) {
ButtonsLists();
return InkWell(
child: Card(
child: GridTile(
......
http://prntscr.com/ndu7rc "Import error"
The code works if I don't have the lists in a separate file and instead have them where the ButtonsLists(); is at.
That's because import will only import you the class written in the file you're referring to. More precisely, The ability to create instances of the class in the imported Dart file
To solve your problem
1- Initialize your lists globally inside ButtonsLists class. (before the Build() method). I'd rather to declare them final
2- Fill your lists with data as you like in the Build() method
3- Create getters to get a copy of your filled lists
4- Create an instance of the ButtonsLists class inside the _LoginPageState class and call the getter of any list whenever you need
The implementation should be something like this:
class ButtonsLists extends StatelessWidget {
final List<MainButtons> _buttonList = new List();
#override
Widget build(BuildContext context) {
//Build your lists here
}
List<MainButtons> getMainButtonsList(){
return _buttonList;
}
Then inside _LoginPageState class create an instance of the class ButtonsLists like this:
ButtonsLists mLists = new ButtonsLists();
and call your list anywhere in the class like this:
mLists.getMainButtonsList();

The argument type '_PostCreateRoute' can't be assigned to the parameter type 'Route<Map>

I am trying to make a social networking site using flutter . This is a feed related page which stores if there are feed available for the user or not and if there are feed it shows it . I am using asynchronous method for action during feed update so while creating on-pressed it is showing an error while creating PostCreateRoute object that the argument type '_PostCreateRoute' can't be assigned to the parameter type 'Route'. and I am new to flutter and if someone can help me out it would be great .
class _FeedActionButtonState extends State<FeedActionButton> {
BuildContext _context;
#override
Widget build(BuildContext context) {
_context = context;
return new FloatingActionButton(
child: new Icon(Icons.add, color:Theme.of(context).iconTheme.color),
onPressed: onPressed,
backgroundColor: Colors.white);
}
onPressed() async{
Mappost=await
Navigator.of(_context).push(new_PostCreateRoute(_context));
if (post!=null &&widget.onPosted!=null){
this .widget.onPosted(post)
}
}
}
It looks like you are passing _PostCreateRoute() as an argument to the push function which only accepts the arguments of type Route().
You first need to wrap your class in a route object like MaterialPageRoute (Android) or CupertinoPageRoute (iOS).
You can try something like:
Navigator.push(_context, MaterialPageRoute(builder: (BuildContext _context) => _PostCreateRoute(_context)));
Make sure you import material.dart or cupertino.dart depending on which route type you go with.

how to decide if my variables shall be inside the class that extend StatefulWidget OR Starte<>?

I have a class QuizPage extends StatefulWidget,
and another class _QuizPageState extends State< QuizPage>
class QuizPage extends StatefulWidget {
var HERE; // or over there ?
#override
_QuizPageState createState() => _QuizPageState();
}
class _QuizPageState extends State<QuizPage> {
var HERE; // or over there ?
#override
Widget build(BuildContext context) {return Container();}
}
What's the difference if any?
I'm new to flutter, but I noticed through the
examples I encountered that if I want to send anything through the
constructor, it has to be in the StatefulWidget and I can access it
inside the State by widget.anything
Variables inside the StatefulWidget subclass cannot change over time. They must be declared as final, or else you'll have a warning.
Adding variables here should be done solely for parameters: Other widgets communicating with this one.
State<T> subclass has much more freedom on that topic. This is where you should put all your internal variables. Whether the change over time or not.

Get BuildContext when not available through parameter

Is there an alternative to Navigator.push which doesn't require a context? Here is my problem.
I have a very nested and deep callstack and not each function has a BuildContext parameter. Is there any other way to get the current BuildContext than through passing it from one function to another?
test1.dart
Widget build(BuildContext) {
...
new GestureDetector(
onTap: () => foo1() // very deep callstack until it calls foo30
...
}
test2.dart
void foo30() {
// need context here like:
BuildContext context = IHopeThatExists.getCurrentContext();
// why do I need that? Navigator.push needs a context or is there an alternative? FYI: I don't need to go back to the previous page though
Navigator.push(context, ..)
}
You can use the Builder widget:
return Builder(
builder: (context) {
return RaisedButton(
onPressed: () {
Navigator.of(context).push(...);
},
...
);
},
);
If your call stack is that deep you might want to consider refactoring =D. But that aside, if you use a StatefulWidget it has a context property which is the same as what is passed to the build function.
And FYI - from the State.build docs:
The BuildContext argument is always the same as the context property
of this State object and will remain the same for the lifetime of this
object. The BuildContext argument is provided redundantly here so that
this method matches the signature for a WidgetBuilder.

Calling constructor super errors with 3 passed, 0 expected

Background: I'm trying to inherit from AnimatedCrossFade to apply this patch https://github.com/flutter/flutter/issues/10243 as a subclass (rather than forking flutter). I'm just learning dart/flutter, and honestly I thought that creating a cross-fade from a loading widget to a network image would have been a really simple thing to try first (it's not easy at all, FadeInImage doesn't crossfade nor does it take a widget [despite the design goal of nearly everything in flutter being a widget],Image.network does not have a onDownloadCompleted callback, and AnimatedCrossFade has the aforementioned bug with centering). Anyway...
Here's the code I'm calling:
class FixedCrossFade extends AnimatedCrossFade {
const FixedCrossFade({
Key key,
#required firstChild,
#required secondChild,
firstCurve: Curves.linear,
secondCurve: Curves.linear,
sizeCurve: Curves.linear,
alignment: Alignment.topCenter,
#required crossFadeState,
#required duration,
layoutBuilder: AnimatedCrossFade.defaultLayoutBuilder,
}) : super(
key,
firstChild,
secondChild,
firstCurve: firstCurve,
secondCurve: secondCurve,
alignment: alignment,
crossFadeState: crossFadeState,
duration: duration,
layoutBuilder: layoutBuilder
);
}
For reference, this is AnimatedCrossFade's constructor:
const AnimatedCrossFade({
Key key,
#required this.firstChild,
#required this.secondChild,
this.firstCurve: Curves.linear,
this.secondCurve: Curves.linear,
this.sizeCurve: Curves.linear,
this.alignment: Alignment.topCenter,
#required this.crossFadeState,
#required this.duration,
this.layoutBuilder: defaultLayoutBuilder,
}) : assert(firstChild != null),
assert(secondChild != null),
assert(firstCurve != null),
assert(secondCurve != null),
assert(sizeCurve != null),
assert(alignment != null),
assert(crossFadeState != null),
assert(duration != null),
assert(layoutBuilder != null),
super(key: key);
My FixedCrossFade class errors with:
error: line 33 pos 8: invalid arguments passed to super class constructor 'AnimatedCrossFade.': 3 passed, 0 expected
Where line number 33 corresponds to the line }) : super(
I'm not actually changing the constructor, I believe all I need to do is overrride createState, and completely reimplement the state object. Coming from a python / C++ background, I was quite surprised that extending AnimatedCrossFade without any changes causes an error:
class FixedCrossFade extends AnimatedCrossFade {}
...
No constructor 'FixedCrossFade' declared in class 'FixedCrossFade'
I'm very very new to dart and flutter, so this is probably a very simple mistake. Any help is appreciated!
As you noticed, the super-constructor has only named parameters, but you are passing key, firstChild and secondChild without a name, so they are positional arguments. Change those to:
}) : super(
key : key,
firstChild: firstChild,
secondChild: secondChild,
firstCurve: firstCurve,
and the super-invocation will work.
You need to add a constructor because constructors are not inherited. They are not instance methods, they are rather more like static methods which are also not inherited. So, for your class to have any constructor, it needs to declare it, and then call a suitable generative super-constructor to create the superclass. It's, admittedly, annoying when all you do is forward arguments.

Resources