I am trying to create a scopedmodel in my flutter project and I can't seem to figure out why I get the error. What is wrong in this scopedmodel implementation? I have a home page with bottom navigator. Inside the profile tab, I fetch the list of followers which I need in a widget deep in the tree so I am trying to use scopedmodel.
The model code is
class RelationshipsModel extends Model {
List<Relationship> relations;
RelationshipsModel(this.relations);
void add(String name) {
relations.add(new Relationship("", "", name, name));
notifyListeners();
}
}
Profile page that creates the scopedmodel is below. Here I get the followers list from Firebase in the state and use it to create the model for the scopedmodel.
class ProfileWidget extends StatefulWidget {
@override
_ProfileWidgetState createState() => _ProfileWidgetState();
}
class _ProfileWidgetState extends State<ProfileWidget> {
@override
initState() {
super.initState();
getCurrentUserDetails();
}
getCurrentUserDetails() async {
_name = await CacheService.getCurrentUser();
var following = await service.getFollowingList(_name);
setState(() {
this._following = following;
});
}
@override
Widget build(BuildContext context) {
if (this._name == null) {
return new Container(
child: const CupertinoActivityIndicator(),
);
}
return ScopedModel<RelationshipsModel>(
model: RelationshipsModel(this._following),
child: Scaffold(
//more stuff
background: new Stack(children: <Widget>[
new CarouselWidget(),
new Align(
alignment: FractionalOffset.topCenter,
heightFactor: 6.0,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//Here I am creating the a widget that shows the list of followers and following
new FollowerInfoWidget(followers: this._followers,
following: this._following),
],
),
),
])),
)
);
}
}
The FollowerInfoWidget is below which calls the ProfileWidget or UserWidget based on the clicked user from the list
class _FollowerState extends State<FollowerWidget> {
Widget buildListTile(BuildContext context, Relationship item) {
return new MergeSemantics(
child: new ListTile(
title: new Text(item.followerId),
onTap: () async {
if (item.followerId == await CacheService.getCurrentUser()) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ProfileWidget()),
);
}
else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>
UserWidget(name: item.followerId)),
);
}
},
trailing: new Icon(Icons.info, color: Theme.of(context).disabledColor),
),
);
}
The button which is FollowUnFollowWidget is part of the UserWidget
class UserWidget extends StatefulWidget {
UserWidget(
{Key key})
: super(key: key);
@override
_UserWidgetState createState() => _UserWidgetState();
}
class _UserWidgetState extends State<UserWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
//more stuff
new FollowerInfoWidget(
followers: this._followers,
following: this._following,
),
new FollowUnFollowWidget ()
And the widget that has the ScopedModelDescendant is below
class FollowUnFollowWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<RelationshipsModel>(
builder: (context, child, model) =>
FloatingActionButton(
onPressed: () {}
//more stuff
)
);
}
}
This code here will push a view which is either a ProfileWidget
or a UserWidget
onTap: () async {
if (item.followerId == await CacheService.getCurrentUser()) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ProfileWidget()),
);
}
else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>
UserWidget(name: item.followerId)),
);
}
},
Since UserWidget
has the FollowUnFollowWidget
the use of ScopedModelDescendant
would not work since there is no ScopedModel
above it. This ScopedModel
is only defined with the ProfileWidget
Looks like you need to add the ScopedModel
to either the top of the build method of UserWidget
or as part of buildListTile