Issue
I have a page where user enters his username and birthday after initial sign in, then I want to return and use this data in previous screen.
In Screen2:
Navigator.pop(context, {'username':username, 'birthday':birthday});
In Screen1:
final userData = await Navigator.pushNamed(context, '/setup_profile');
final/var works well for single variable such as String but doesn't work for maps because it doesn't know returning object is actually a map.
Naturally you can't use userData['username']
without specifying it is a Map and I don't understand how to specify it.
I've tried
Map<String, dynamic> userData = await Navigator.pushNamed(context, '/register');
It didn't work I received this error:
Unhandled Exception: type 'MaterialPageRoute<dynamic>' is not a subtype of type 'Route<Map<String, dynamic>>'
Then I tried
Route route = await Navigator.pushNamed(context, '/register');
Map<String, dynamic> data = route.currentResult;
This didn't work as well, I got same error
Unhandled Exception: type 'MaterialPageRoute<dynamic>' is not a subtype of type 'Route<Route<dynamic>>'
Simply put I want to use that returned Map in Screen1.
Main problem is I don't know how to specify returning data, is it a custom class or map or list or something else. How can I specify return type from Navigator.pop?
Solution
Navigator.pop()
allows you to provide an optional generic typed argument.
A good practice to properly pass arguments using the Navigator
, not just for the .pop()
method, is by creating page/screen argument objects.
screen1.dart
class Screen1Arguments {
Map<String, dynamic> someMapVariable;
Screen1Arguments(this.someMapVariable);
}
Based on your setup, you can now retrieve the value from Screen2
from Screen1
like this:
screen1.dart
RaisedButton(
child: Text('Open Second Screen'),
onPressed: () async {
final Screen1Arguments args = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Screen2(),
),
);
print("args ${args.someMapVariable}");
},
),
Given that now you are using Screen1Arguments
as your typed argument for the .pop()
method, you can now conveniently pass Map
variables in your Screen2
:
screen2.dart
RaisedButton(
child: Text('Close Screen'),
onPressed: () {
Navigator.pop(
context,
Screen1Arguments(
{
"key1": "value1",
"key2": "value2",
"key3": 3,
},
),
);
},
),
In addition, you can still add other variables with different data types (aside from Map
) just like any other model classes or objects you have in your app:
class Screen1Arguments {
Map<String, dynamic> someMapVariable;
String username;
Date birthday;
Screen1Arguments(this.someMapVariable, this.username, this.birthday);
}
Further reading
- https://api.flutter.dev/flutter/widgets/Navigator/pop.html
- https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments
Answered By - Joshua de Guzman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.