Transfer variable to other class - flutter

I am trying to get a list from class to the other. But I want it to only be transferred after it has got a value assigned from a Future. Is there a way to do so (something like a setState method that acts across classes) My code is here:
class Design extends StatefulWidget {
#override
_DesignState createState() => _DesignState();
}
class _DesignState extends State<Design>{
var Data;
#override
void initState() {
super.initState();
comparer().then((List returnedV){
setState(() {
Data = returnedV;
});
});
}
Future<List> compare() async {
...
return dataDevice
}
}
class AboutSheet extends StatefulWidget {
final List Data;
AboutSheet({#required this.Data});
#override
_AboutSheetState createState() => _AboutSheetState();
}
class _AboutSheetState extends State<AboutSheet> {
}
Every time I use the variable Data in the second class it has the value null. I think it's because I have defined it before with the value null and it's pulling that and is not waiting for the future to assign a value to it. I can't think of a workaround. I would really appreciate your help!

What you are referring to is a state management solution. There is a lot of them, with each their pros and cons. I (and the Flutter team) would suggest Provider.
Take a look at this : List of state management approaches

Related

How to replace copyWith so as not to copy, but to create a new state?

I have a bloc which is responsible for switching indexes in the Navogation Bottom Bar.It is implemented in such a way that it copies the old state and changes it. I need to replace copyWith and make it not copy but create a new state. How can this be implemented and rewritten given bloc?
class BottomNavyBloc extends Bloc<BottomNavyEvent, BottomNavyState> {
BottomNavyBloc() : super(const BottomNavyState()) {
on<ChangePageEvent>(
(event, emit) => emit(
state.copyWith(index: event.index),
),
);
}
}
abstract class BottomNavyEvent extends Equatable {
const BottomNavyEvent();
#override
List<Object> get props => [];
}
class ChangePageEvent extends BottomNavyEvent {
final int index;
const ChangePageEvent({
required this.index,
});
#override
List<Object> get props => [index];
}
My state:
class BottomNavyState extends Equatable {
const BottomNavyState({
this.index = 0,
});
final int index;
#override
List<Object> get props => [index];
}
class ChangePageState extends BottomNavyState {
}
We use
emit(state.copyWith(index: event.index))
to say that we are copying all the elements from the previous state by changing index.
Your state BottomNavyState has only one variable as of now. So, the above copyWith acts similar to using emitting new state.
We should not try to change or override the method copyWith because it beats the method's actual purpose.
Instead, you could use
emit(BottomNavyState(index: event.index))
to use a new state constructor instead of copying from previous state.

Unable to set callback function . Error Says: 'DropDown' must have a method body because 'ListLayout' isn't abstract

I have a drop down class and a list view. I want to change the state of list view when the drop down item is changed. To do so, i have to setState of list from dropdown class.I learnt about callback function and was trying to implement it. But I got an error.
My Code for drop down class:
class DropDown extends StatefulWidget {
final Function _callBack;
DropDown({#required void callBack()}) :
_callBack = callBack;
#override
_DropDownState createState() => _DropDownState();
}
Code for ListLayout is here:
class ListLayout extends StatefulWidget {
DropDown(dropDownItemChanged );//Error comes here saying 'DropDown' must have a method body
// because 'ListLayout' isn't abstract. Try making 'ListLayout' abstract, or adding a body to
//'DropDown'.
#override
_ListLayoutState createState() => _ListLayoutState();
}
class _ListLayoutState extends State<ListLayout> {
void dropDownItemChanged (String data) {
setState(() {
....
}
}
});
}
#override
Widget build(BuildContext context) {
return ....;
}
}
I would be grateful if somebody could answer this
I am sorry, I was not supposed to instantiate DropDown from ListLayout , because DropDown is not a child of ListLayout. May be this helps someone.

Flutter: A variable passed to the next screen becomes null

I want to pass a variable to the next screen but it becomes null in the next screen. what am I wrong with this? My code is like below.
first_screen.dart
onTap: () {
print(doc); // Prints out Instance of `DocumentSnapshot` on log
Navigator.of(context).pushNamed('/second', arguments: doc);
},
second_screen.dart
class SecondScreen extends StatefulWidget {
final DocumentSnapshot doc;
SecondScreen({
this.doc,
});
#override
State<StatefulWidget> createState() {
return _SecondScreenStateState();
}
}
class _SecondScreenState extends State<SecondScreen> {
#override
void initState() {
super.initState();
print(widget.doc); // Prints out null here
}
I tried with othe data types but all variables become null in the next screen.
You have to pass argument like this:
Navigator.of(context).pushNamed('/second', arguments: doc);
for you is true but, use the ModalRoute.of() method to returns the current route with the arguments like this:
final doc = ModalRoute.of(context).settings.arguments as String;
I assumed that doc is String.
If you're sharing data between widgets (screens) try looking at InheritedWidget.Take a look at https://www.youtube.com/watch?v=1t-8rBCGBYw. You can also look at state management packages like provider which is pretty easy to understand or a bloc. These will save you in the long run.

How to access it's static constant from instance of an object?

I have an object that has static constant which I need to reach from its instance.
class ChatsScreen extends StatefulWidget {
var arguments;
static const name = ADatas.chatRoute;
ChatsScreen(this.arguments);
createState() => ChatsScreenState();
}
In above class' State object, I want to call static const name. Above class' State object's code:
class ChatsScreenState extends State<ChatsScreen> with RouteHelper{
String userName = "";
var textEditingController = TextEditingController();
#override
void initState() {
getRouteName(widget); //=> as I understand and see on the VSCode, its the ChatsScreen object.
super.initState();
}
}
I'm trying to implement an interface so I don't know the actually class name while writing the interface. And I thought that I can reach its static constant if I know its actual class. And I wrote something like this but it seems not to be possible. I guess I have a misunderstanding.
class RouteHelper{
String getRouteName(dynamic instance){
if(instance is StatefulWidget){
return instance.runtimeType.name; // => !!!
}
}
}
Note: I'm not trying to get the route name in actual. It's just a concept that i used in this question, so please don't refer better way to get the route name in flutter.
You can't do it like that, people have talked about this in this issue.
However you can kinda do it using class members and typing system.
abstract class Routed {
String getClassRoute();
}
class ChatsScreen extends StatefulWidget implements Routed {
var arguments;
static const name = "myexampleroutename";
ChatsScreen(this.arguments);
createState() => ChatsScreenState();
#override
String getClassRoute() {
return ChatsScreen.name;
}
}
class RouteHelper {
String getRouteName(Routed instance) {
return instance.getClassRoute();
}
}
I said you can't, but with dart:mirrors it is possible, however it is banned on Flutter packages. There is reflectable package that tries to fix that using code generation, but I am not aware of it's status/reliability.

Flutter state outside State object

I keep primitive states inside State. But for objects, the following works:
class _Like extends StatefulWidget {
final Post _post; <-- mutable object is here
_Like(this._post);
#override
State<StatefulWidget> createState() => _LikeState();
}
class _LikeState extends State<_Like> {
...
_like() {
setState(() {
widget._post.liked = !widget._post.liked; <-- mutated here
});
}
...
}
What would the be reason not to use this approach? (As opposed to moving the state inside State, preferably as primitive bool)
Perhaps because initState() is in the State class, which your StatefulWidget can't call. So your entire state should be in your State class to permit that.