'ProxyProvider - how to call proxy from its sub-providers?
What would be the correct way to call (and pass values to) ProxyProvider from its "sub"providers?
Currently I'm passing a callback function to "sub"provider as a parameter, storing it as a Function and then I can call it when needed.
It works in a sense that ProxyProvider is called (and value is passed), but at the same time it breaks notifyListeners(), which is called next - searches getter in "sub"provider (and can't find it) despite that Consumer is used just for ProxyProvider.
This is the error I receive:
error: org-dartlang-debug:synthetic_debug_expression:1:1: Error: The getter 'audInd' isn't defined for the class 'AudioModel'.
- 'AudioModel' is from 'package:quiz_game_new/models/audioModel.dart' ('lib/models/audioModel.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'audInd'. audInd ^^^^^^
Code
Provider (audioModel.dart):
class AudioModel extends ChangeNotifier {
int _audioIndex = -1;
Function? audioIndexChanged;
void setCallbacks(Function _audioPlaybackCompleted, Function _audioIndexChanged) {
audioPlaybackCompleted = _audioPlaybackCompleted;
audioIndexChanged = _audioIndexChanged;
}
//Some code that changes _audioIndex and afterwards calls audioIndexChanged!(_audioIndex)
}
ProxyProvider (commonModel.dart)
class CommonModel extends ChangeNotifier {
CommonModel(this.audioModel);
final AudioModel audioModel;
int _audioIndex = -1;
int get audioIndex => _audioIndex;
void setCallbacksForAudioPlayback() {
audioModel.setCallbacks(audioPlaybackCompleted, audioIndexChanged);
}
void audioIndexChanged(int audInd) {
_audioIndex = audInd;
notifyListeners();
}
}
Initialization:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<STTModel>(create: (context) => STTModel()),
ChangeNotifierProvider<QuestionModel>(
create: (context) => QuestionModel()),
ChangeNotifierProvider<AudioModel>(create: (context) => AudioModel()),
ChangeNotifierProxyProvider3<STTModel, QuestionModel, AudioModel,
CommonModel>(
create: (BuildContext context) => CommonModel(
Provider.of<STTModel>(context, listen: false),
Provider.of<QuestionModel>(context, listen: false),
Provider.of<AudioModel>(context, listen: false)),
update:
(context, sttModel, questionModel, audioModel, commonModel) =>
CommonModel(sttModel, questionModel, audioModel))
],
child: MaterialApp(
title: 'Flutter Demo',
initialRoute: '/',
routes: {
'/': (context) => ScreenMainMenu(),
'/game': (context) => ScreenGame(),
}));
}
}
Solution 1:[1]
What would be the correct way to call (and pass values to) ProxyProvider from its "sub"providers?
I'm not a big fan of "nested" Providers : it often leads to this kind of issues and doesn't ease the readability.
In my projects, I usually use a Provider for each Feature, which I declare and Consume at the lowest level possible.
In your case, I guess I'd juste have used your STTModel, QuestionModel and AudioModel and would have forgotten the idea of a CommonModel (whom only job is is to merge all your Providers I guess?).
You can still keep your logic, but you should take in consideration the following :
In your AudioModel class, update the method where the _audioIndex and add a notifyListeners()
class AudioModel extends ChangeNotifier {
//...
int get audioIndex => _audioIndex;
void updateIndex(int index) {
_audioIndex = index;
//The rest of your code
notifyListeners();
}
//...
}
The creation of your Providers looks alright, but consider updating the update method of your ChangeNotifierProxyProvider for something like that :
update: (_, sttModel, questionModel, audioModel) =>
commonModel!..update(sttModel, questionModel, audioModel),
and in your CommonModel
void update(SttModel sttModelUpdate, QuestionModel questionModelUpdate, AudioModel audioModelUpdate) {
audioModel = audioModelUpdate;
questionModel = questionModelUpdate;
sttModel = sttModelUpdate;
//Retrieve the index here from your audioModel
_audioIndex = audioModel.audioIndex;
notifyListeners();
}
This way, whenever you call your updateIndex method in your AudioModel class, the notifyListeners() will update the CommonModel and you'll have the _audioIndex up to date.
And then it should work fine, no need for your callback methods anymore !
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | FDuhen |
