Flutter - Sending data & defining additional data between pages - flutter

I am running into a problem which I find difficult to describe.
I have a class with two variables. On page 1, I would like to show variable 1. Then, if the user progresses to page 2, I would like to display a widget with variable 1 and 2. I understood how to pass data from one screen to another, but how would I progress if I had to get more data one the second page.
This is the class:
class Dog {
String name;
String age;
Dog({ this.name, this.age });
}
On the first page, I only define the String name, but not the age. Hence, when the user progresses to the second page, I pass the name data as follows (from a list of dogs):
Navigator.push(context,
MaterialPageRoute(
builder: (context) => Screen2(dog: dogs[index]),
),
);
On the second screen, I would like to show a statelesswidget with both class variables, but I only passed one:
final Dog dog;
Screen2({Key key, #required this.dog}) : super(key: key);
In the last code, "this.dog" only includes the name String.
How could I now add the age String as well? Do I have to add it to Navigator.push, or is there a way to add it in the statelesswidget?
Thanks so much in advance for any guidance you can give me!

Related

Changes in Object from Second Screen is also Changing the Value in First Screen in flutter dart

A class Object passing from First Screen to the second Screen While on the second screen when the object changed its value, it's also changing the value on first screen.
Code of First Screen. (widget.templateModel is an object class that i am passing to the second screen)
Navigator.push(context,MaterialPageRoute(builder: (context) =>
EditEmojiTextTemplateScreen(templateModel: widget.templateModel,));
Code of Second Screen (On the second screen i am receiving the object and when i am changing the value of widget.templateModel it also changing the value on the first screen for a simple understandable code below i changed the value in initState while in the gif i am changing value in TextFormField)
class EditEmojiTextTemplateScreen extends StatefulWidget {
final TemplateModel templateModel;
EditEmojiTextTemplateScreen({
Key? key,
required this.templateModel,
}) : super(key: key);
#override
State<EditEmojiTextTemplateScreen> createState() =>
_EditEmojiTextTemplateScreenState();
}
class _EditEmojiTextTemplateScreenState
extends State<EditEmojiTextTemplateScreen> {
final SharedPreferences sharedPreferences = sl();
var txtNameController = TextEditingController();
var txtColorController = TextEditingController();
_EditEmojiTextTemplateScreenState();
#override
void initState() {
widget.templateModel.emoji[0].titleTwo = "kdfff"; //here i am changing the value and it also changing the value on first screen and i dont want this behavior of this object
super.initState();
}
Note: This is happening because of widget variable as mentioned in the documentation but i don't know how to prevent this behavior.
package:flutter/src/widgets/framework.dart
The current configuration.
A [State] object's configuration is the corresponding [StatefulWidget]
instance. This property is initialized by the framework before calling
[initState]. If the parent updates this location in the tree to a new
widget with the same [runtimeType] and [Widget.key] as the current
configuration, the framework will update this property to refer to the
new widget and then call [didUpdateWidget], passing the old
configuration as an argument.
Now I see what you are trying to do.
You could initialize a NEW istance of TemplateModel in the InitState of the second screen.
Then, set the new object's properties like this (or write a cleaner method to do that):
newObject.property1 = oldObject.property1;
newObject.property2 = oldObject.property2;
...
Once the user presses the save button, change oldObject's properties again, so that the first page updates.
You might want to take a look at state management to better understand how to approach this kind of problems.
As the other answer suggests, take a look at state management solutions.
Also keep the models immutable by creating them with final fields. Then to modify, create new instances via copyWith()
Please update you code after navigation.then method
template = snapshot.data;

How to get TextField content from screen to screen?

still new to flutter and I was trying to take multiple values from TextFields in a form to display them in a new screen inside multiple Text elements.
Can someone explain how to do it ?
There are three ways to do it
First method: You can define a class and assign values to it like this:
class Global(){
String text;
}
and then you can import it and assign values or use it like this:
// assign data
Global().text = TextField_controller; // I assume you have already implemented a TextField
// use it
Text(Global().text)
This method is good for passing data between multiple pages but it's not recommended because you can't update the screen when the value changes, it's only good when you need to pass a static variable between multiple pages, for example a user name
Second method: passing data to next page directly
Make the SecondScreen constructor take a parameter for the type of data that you want to send to it. In this particular example, the data is defined to be a String value and is set here with this.text.
class SecondScreen extends StatelessWidget {
final String text;
SecondScreen({Key key, #required this.text}) : super(key: key);
...
Then use the Navigator in the FirstScreen widget to push a route to the SecondScreen widget. You put the data that you want to send as a parameter in its constructor.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(text: 'Hello',),
));
this method is great for passing data from a parent page to a child page however it can quickly become a nightmare if you want to pass the data to several children down the widget tree or move data back to the parent widget, in that case you can use method 1 or
Third method: using Provider, which is the recommended way, it is similar to the first method but with provider you can ``notify``` all of the listeners to the provider class, meaning you can update the widget whenever the the variable updates, I strongly recommend reading the documentation or watching some YouTube videos, but in short you can use it like this:
after installing the provider package you define your class:
Global extends ChangeNotifierProvider(){
String text;
}
and then add it to the root of your app in main.dart:
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Global()),
),
],
child: MyApp(),
);
}
and then you define your provider wherever you need to use it
Provider.of<Global>(context, listen: false); // Note that if you want to listen to changes you have to set listen to true
// then you can access your variable like in method 1
insatnce.text = TextField_controller;
// and then you can use it anywhere
Text(instance.text);
again if you find this confusing read the documentation or watch some videos

flutter:: Is it possible to get string from another file in stateful?

How to get data from previous page when using stateful String link.
Is it possible to get string from another file in stateful?
I need to get the string from another file b into the stateful of file a. In case of stateless this was possible, but in stateful it is not possible.
Is there a way to solve this?
I hate to disagree but using global variables in this situation when you can fix your problem easily is not wise although it works and it is very easy.
if you want to send data to another page via pushing a new page you can always use that newPage Constructor
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BalancePage(
items: "item",
),
),
);
New Page
class BalancePage extends StatefulWidget {
String? items;
BalancePage({
this.items,
});
#override
_BalancePageState createState() => _BalancePageState();
}
if you want to take data from another class you can set a getter
class newVal(){
String val ="ss";
String getVal(){
return val;
}
}
and you can call it anywhere like this
String ss = newVal().getVal;

How to get the Number of the item in a List in Flutter in a Text Widget

I have a list from a Model Class which generate a list:
List<User> user = [
currentUser,
stefano,
roberta,
sabrina,
carmine,
paolo,
calogero,
ernesto,
oreste,
];
each item of this list has his own data in this case I have 8 users in this list and I would the Number 8 appears in a TextWidget in Flutter but I can achieve that even useing int.parse.
at the moment I import the Class:
final Consultant consultant;
final User user;
final Message message;
const DashBoardScreen({Key key, this.consultant, this.user, this.message}) : super(key: key);
and other list and I am trying into a tezxt widget to get the number with:
Text(int.parse(user.length))
but unsuccesfully.
You can directly import the list if you are using Navigator, another thing make sure you have passed the list/class correctly.
You are getting error because Text widget needs a String not int so use a string interpolation or just add .toString at the end.
And change your code to this
Text(${widget.user.length}), // or to this Text(widget.user.length.toString()),

Flutter: how to Pop multiple parameters

This is problably sthg simple, I would like to pop a widget and to pass different parameters, here is what I have :
class MyScreen extends StatefulWidget {
final String param0;
final String param1;
final String param2;
MyScreen(param0,param1,param2);
#override
MyState createState() => new MyScreenState();
}
...
I would like to go back to this widget passing parameters, something like this :
Navigator.pop(context, "NewParam0", "NewParam1", "NewParam2");
but it doesn't work.
I can pop with 1 parameter and the context, but it doesn't work with multiple parameters,
Any idea?
Yep, the solution is simple! The way I've dealt with this is by popping an object. For instance, a Map<String, String>:
Navigator.pop(context,
{"NewParam0": "param0value", "NewParam1": "param1value", "NewParam2": "param2value"}
);
(see https://api.flutter.dev/flutter/widgets/Navigator/pop.html and https://flutter.dev/docs/cookbook/navigation/returning-data)
You could also make a lightweight class to pop that will populate default params, etc. if you have a lot of complexity to pass back and forth, though at that point, I might try to rework my state management a little bit.