Hi, this probably isn't a bug, but I don't understand what is going on here.
I get thouse 2 errors:
- Could not find the correct Provider<SecondPageBloc> above this ChangeStringWithButton Widget
- There are multiple heroes that share the same tag within a subtree.
This is my MultiProvider at the Myapp() main page:
home: MultiProvider(
providers: [
Provider<CounterBloc>(
value: CounterBloc(),
),
Provider<UserBloc>(
value: UserBloc(),
),
Provider<SecondPageBloc>(
value: SecondPageBloc(),
),
],
child: BlocCounterPage(), // the main page
),
depending on the child ^ which i am using in the MultiProvider that widget is working but if I navigate to another page with the drawer I get the error mentioned above
The Navigation from the Drawer:
Divider(height: 2.0, color: Colors.blue,),
ListTile(
leading: Icon(Icons.text_fields),
title: Text('Change Text with button'),
onTap: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) {
return ChangeStringWithButton();
}));
}
),
This is a simple counter bloc
import 'dart:async';
import 'package:rxdart/rxdart.dart';
import 'package:simple_bloc/api/db_api.dart';
import 'package:simple_bloc/models/user.dart';
class UserBloc {
User _user;
final _userController = BehaviorSubject<User>();
Stream<User> get outUser => _userController.stream;
UserBloc(){
init();
}
void init() async {
_user = await api.getUser();
_userController.add(_user);
}
void updateUser(User user){
_user = user;
_userController.add(_user);
}
}
Another thing If I use pushReplacment to navigate I get a big error:
Could not find the correct Provider<SecondPageBloc> above this ChangeStringWithButton Widget
This happens because you added your providers on home field instead of wrapping the entire MaterialApp
As such, other routes cannot access providers.
In your case,
DO:
Provider<int>(
value: 42,
child: MaterialApp(home: Home()),
)
DON'T:
MaterialApp(
home: Provider<int>(
value: 42,
child: Home(),
),
)
Thanks, that is correct, one more question:
I am still getting an issue (a blank black page) when I use "push" on the navigator instead of "pushReplacement"
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return ThemeSwitcher();
})),
),
Error:
There are multiple heroes that share the same tag within a subtree.
That's unrelated to provider package. You may want to ask that on StackOverflow instead
keeps giving me this error: Error: Could not find the correct Provider
`import 'package:api_work/authentication_service.dart';
import 'package:provider/provider.dart';
void main() => runApp(
ChangeNotifierProvider
child: MyApp(),
builder: (BuildContext context){
return AuthService();
},
),
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: FutureBuilder(
// get the Provider, and call the getUser method
future: Provider.of
// wait for the future to resolve and render the appropriate
// widget for HomePage or LoginPage
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return snapshot.hasData ? HomePage() : LoginPage();
} else {
return Container(color: Colors.white);
}
},
),
);
}
}
`
Error: Could not find the correct Provider
You must specify the type of the object you want to obtain when calling Provider.of.
I also have an issue....
I try to trigger a simple action from a different class, using provider package. What I did:
1) I created a ChangeNotifier class named MySchedule which has a getter and a setter:
class MySchedule extends ChangeNotifier {
bool _foodSet = false;
bool get foodSet => _foodSet;
set foodSet(bool newBool) {
_foodSet = newBool;
notifyListeners();
}
}
The widget tree of this widget is the following (I made it shorter, than the original) - this is inside a stateful widget class
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
builder: (context) => MySchedule(),
child: Scaffold(
body: Stack(
children: <Widget>[
Container(
child: AnotherWidgetWhichHasLotOfChild()
),
),
AnimatedContainer(
curve: Curves.fastOutSlowIn,
duration: Duration(milliseconds: 500),
alignment: Alignment(left, -1),
child: MenuSheet(close: toggleMainMenu, change: changeToTab),
),
FoodDetailsClass()
],
),
));
}
The FoodDetailsClass has a container in a visibility, which 'visible' boolean I want to change with the provider:
class FoodDetailsClass extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<MySchedule>(
builder: (context, provider, child) => Visibility(
visible: provider.foodSet,
child: Center(
child: Container(
height: 600,
width: 400,
color: Colors.red,
),
),
));
}
}
I want to change it from inside the "AnotherWidgetWhichHasLotOfChild()" class in this way: Inside the above mentioned class there is a following call (but it throws an error):
GestureDetector(
onTap: (){
final schedule2 =
Provider.of<MySchedule>(context);
schedule2.foodSet = true;
}
The error is: Error: Could not find the correct Provider above this FoodList Widget
To fix, please:
Ensure the Provider is an ancestor to this FoodList Widget
@janosdupai
I have the same problem, have you fix it?
I have an issue.
When i open up the drawer from the below code it says that " Could not find the correct Provider
class _SettingsFormState extends State
final _formkey = GlobalKey
final List
//form value
String _currentName='';
String _currentSugars=null;
int _currentStrength;
@override
Widget build(BuildContext context){
final user=Provider.of
return StreamBuilder<UserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if(snapshot.hasData){
UserData userData=snapshot.data;
return Form(
key: _formkey,
child: Column(
children: <Widget>[
Text(
'Update your Brew Settings',
style: TextStyle(
fontSize: 18.0
),
),
SizedBox(
height: 20,
),
TextFormField(
initialValue: userData.name,
decoration: textInputDecoration,
validator: (val)=>val.isEmpty?'Please enter a name':null,
onChanged: (val)=>setState(()=>_currentName=val),
),
SizedBox(
height: 20,
),
DropdownButtonFormField(
decoration: textInputDecoration,
value: _currentSugars ?? userData.sugars,
items: sugars.map((sugar){
return DropdownMenuItem(
value: sugar,
child: Text(
'$sugar sugar'
),
);
}).toList(),
onChanged: (value) => setState(() => _currentSugars = value ),
),
Slider(
value: (_currentStrength??100).toDouble(),
min: 100,
max: 900,
divisions: 8,
activeColor: Colors.brown[_currentStrength??100],
inactiveColor: Colors.brown[_currentStrength??100],
onChanged: (value) => setState(() => _currentStrength = value.round() ),
),
RaisedButton(
color: Colors.pink[400],
child: Text(
'Update',
style: TextStyle(
color: Colors.white
),
),
onPressed:()async{
print(_currentName);
print(_currentSugars);
print(_currentStrength);
},
)
],
),
);
}
else{
return null;
}
}
);
}
}
I had the same problem with a Medium tutorial. You might try adding your type after "Provider.of", i.e.: Provider.of<AuthService>(context).
class MyApp extends StatelessWidget {
final geoService = GeolocatorService();
@override
Widget build(BuildContext context) {
return FutureProvider<dynamic>(
create: (context) async => geoService.getInitialLocation(),
child: MaterialApp(
home: Consumer<Position>(
builder: (context, position, widget) {
return Maps(position);
},
),
),
);
}
}
Change your code to FutureProvider<Position>
Most helpful comment
This happens because you added your providers on
homefield instead of wrapping the entireMaterialAppAs such, other routes cannot access providers.
In your case,
DO:
DON'T: