Flutter : Can't access data passed from another screen - flutter

I'm trying to build 2 screens one contains a list of products and the second has product details, I'm using Firebase to store data and so I fetch the data from Firestore in the first screen and it all works perfectly.
However, in the second screen, I pass product data correctly using Navigator but I cannot use that data in my UI.
Here is the code for my second screen:
As you can see I cannot use the name variable in my widget tree, I've seen videos on youtube and I found that some people use state management to solve this problem, but for my case I just want to pass data and display it.

The way you've passed the data is correct but the way you've accessed the data isn't.
Whenever you try to access the variables of a Class in its state, you do that using widget. So, to access the name or other variables, just do as follows:
widget.name
Additionally, if the only purpose is to pass and display the data, then, there's no need of a StatefulWidget, use a StatelessWidget instead.

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.
For that you can use widget.key, this will work fine for you.

Related

Where is Flutter's Navigator declared?

When creating a Flutter application,
we use a Navigator to move back and forth between screens.
In my application, I have some class instances that
I want to share with all child widgets in the hierarchy.
An example is a Data Base driver class (stateful)
which holds all functionality of reading/writing to the actual database.
Currently - the 'main' function is initializing it,
then the resulting object is passed through all
constructors of the participating widgets.
How do I make it behave like the Navigator
so it would be available in the global scope
without importing it or passing it through a chain of constructors?
I would gladly accept any other approaches,
and still, if you can also address the exact question - I would be grateful :)
I opened the code of Navigator, Stateless and Stateful widgets,
I tried to google for the source of that Navigator instance
but came up with nothing helpful.
Have you tried using InheritedWidget?
From the docs:
Base class for widgets that efficiently propagate information down the tree.
Create DataBaseDriver class as inherited Widget class, access it in its child class using context as DataBaseDriver.of(context)

With flutter, how to add a Provider later to the application?

I have a flutter application which uses a MultiProvider widget at the root of the widgets tree.
The problem is, I need to add a ChangeNotifierProvider to the MultiProvider widget, but later because I can't create it at the beginning (well I could but it makes more sense to do it later *).
How am I supposed to do?
(* for more details about why I would like to create the ChangeNotifierProvider later: The associated ChangeNotifier represents a bluetooth connection that will not be available at the start of the application.)
In these situations I create Provider with object which have some initial values and later I change initial values to actual.

How to change a value in a text field and have it show up on another screen (Flutter)?

I'm trying to have the user put information in a TextField on one screen and then save that info when they press "Save". Then I want this text to show up on another screen in another Container (say it asks for their name, they put it in the TextField, press the Button called "Save", it takes them back to the other screen, and the box that previously said "Name" now says "[The name the user entered]").
Thank you in advance for any help!!
Use StateManagement Libraries like flutter_bloc,provider,mobx, getX.
This way you will be able to save your data and use in in any part of your app
There are multiple ways of going about doing this.
You can pass the value through the constructors of the screens you're navigating to (for e.g.
MaterialPageRoute(builder: (context) => NewPage(name: nameValue))
If you want to use this value in multiple places in your application, you can consider storing it in a config class of sorts (i.e., create a class Config as a singleton (only once instance allowed), and store the name there while saving like
Config.name = nameValue. Then, anywhere in your app, you'd access it as Config.name)
If you want this value to be used anywhere else in the app, but also want it to be persistent, then it's probably best to store it as SharedPreferences or in a database. Look into the sharedpreferences package, or sqflite package for Flutter.

What is the best form to pass data between screen with GetX?

I am new on Flutter, and I am using GetX.
I want to do a Stepper for registering, and I want to pass one object between 4 screens and fill some data on each screen.
What is the best method to do that? I was thinking to put a UserModel on a controller and pass it between screens.
Thank you so much.
Generally you don't need to manually pass around data to different pages when using most state management solutions. You store the relevant data in a single instance of the object that you access from anywhere.
class StepController extends GetxController {
// any data in this class is accessible from anywhere and doesn't
// need to be manually passed to any pages
}
Use the variables you create in the GetX class for the Steps and then from anywhere in the app you find the controller with
final controller = Get.find<StepController>();
Just make sure you initialize once it at some point with
Get.put(StepController());
I haven't use GetX but MobX(+provider). In your case, I think dependency injection is best way to share store between screens, you can consume the stores everywhere, so you dont need to pass data to other screen.

Flutter Riverpod: How to create different instances of the same provider for each Stateful widget on a GridView

I have a GridView which contains a list of StatefulWidgets that shows a preview of the image being uploaded and the progress of the upload for that image.
Each widget on the list should have its own state where some of them can upload successfully and others may fail, so the user can retry only those images that failed to upload.
The problem is:
Riverpod is only able to create an instance and that same instance is shared over the whole project. So, if I use Riverpod to track the state of each image, all images on the GridView will share the same state instead of each one have its own state.
Is there a way to use the same provider, but instead of get the same instance every time I call context.read(provider) or watch(provider.state) I get a new independent and fresh one?
You're looking for the .family modifier. See the docs here. You could pass an id or key as the parameter to your StateProvider.
For example:
final imageProvider = StateProvider.family<ImageModel, String>((ref, id) => ...);