How to use provider to update class with multiple instance? - flutter

I am learning the provider package. I have a class called person.
Person(this.name,this.amount);
The person is displayed in a list.
How do I pass the particular instance of a person to the change notifier so that I can update the person amount?

Have you considered having the Provider class be on List<Person>? Then you could update a specific instance, and the change would be notified downward.

Related

Make bloc instances global across a Flutter app and access them by some identifier in a dependency injected fashion way

I have multiple model objects delivered by some data source in my Flutter app, each is identified by its ID (an integer field).
Each model and its state can be represented in multiple widget.
I'm making a bloc object for each model object (for example a model with ID of 3 shown in multiple widgets and they should share the same bloc instance).
From some of these widgets, I can send an event to the bloc instance, and have a new state, and of course, this state should be represented in all of the widgets that are sharing the bloc instance.
The scenario in my mind should be as follows when fetching the data:
1- Each model object fetched from some data source and is delivered to the presentation should search for its corresponding bloc instance.
2- If the bloc instance is created, use this bloc instance (and update its state if necessary).
3- If the bloc instance is not created, create one and use it.
My main problem is, I can't seem to be able to create those bloc instances globally, and access them in a "dependency injected" way. The dependency is the bloc instance and identified by the model ID.
I normally use get_it to register singleton instances, but now I need "Singleton instances uniquely identified by the model IDs"
Also, since blocs opens streams, these should be closed by hand since I think we can't use BlocProvider widgets in my case. If there is a solution to that, that would be much appreciated too.

Updating provider class from outside widget

I'm new into flutter and im using the provider package for state management and i have a typical scenario where messages are coming as event and handling this event is written in a separate class, as soon as a message arrives I have to update the message list which is defined in the provider class to which the other widgets are listening
Now how can I update the message list in the provider class from the class where the event occurs? (I cannot use provider.of(context) since it is a plain class and i don't have access to buildcontext )
I have tried creating a new class of the provider class and then updating the message list but for some reason, it is creating a different instance of the provider class
Provider is a dependency injection package that specifically uses the widget tree (i.e. the build context) to pass around instances of classes. If you don't have access to a build context, you can't get the instance.
Instead, you're going to want to use something like get_it or flutter_bloc for state management that doesn't require a build context. Alternatively, you could change the class emitting the events to be a singleton.

Access on ViewControllerClass

I linked a TableViewController from storyboard to a class. In a different class I implemented some network request functionality and I would like, as soon as I receive responses, update data in my TableViewController-Class. Is there any way I can address this specific instance of class that contains the table etc.?
One way to solve this problem is to access a field of the NetworkClass by implementing a Timer in the TVC-Class, it works, but is probably not the best way to solve the problem.
Is there a way to get e.g. an id of a class and a function that lets me create an object with this id, so that I can simply access field and methods of it
Thanks in advance
Julian

Create a variable/object/resource that is accessible through entire application in ZF2

To be specific, I need to create an array variable that will be used for caching data, but I don't want to use ZF2 Cache Adapter.
I've tried to create a invokable class that would be used to instantiate object of my class that contains methods for setting and getting values from array that is also defined as a property of that class. As far as I understand, service manager treats all services as shared by default, which is supposed to create only one instance off my class when I get the service by service manager method get for the first time. But this doesn't work, if I get that service in different actions in my Controller class, which is what I need to do. So, how am I supposed to achieve this effect? Create an object that is available application-wide?
I had this kind of problem with managing a cart.
My cart is modeled by a CartManager, which is a unique instance for a user (session) and until paiement (cart is persisted in database).
I register my CartManager as a Service to build the first instance, this instance is built during an event handler attached on MvcEvent::EVENT_ROUTE, once built I override the CartManager service with my Instance, this way wherever I call the service, my first instance is served.
Then I persist (session or database) my Instance in an other event handler attached on MvcEvent::EVENT_FINISH.
All the event handlers are attached in Module::onBoostrap()

Cross-Activity references using GWT with Gin

I have a GWT MVP application using Activities and Places. This is inspired by Mauro Bertapelle's sample (in this thread), apparently based on some of Thomas Broyer's work.
Here's the problem: I have LoginActivity make an RPC call, which for a successful login, returns a User. This user has a role (e.g., admin, regular user, guest). Several Views and Activities, including a NavigatorView, depend on this role for what they show or do. How do I get this User instance to the other Activities?
I do not have a ClientFactory; injection (Gin) is used for instantiating the Views in the ActivityProviders which provide my Activities/Presenters, and the ActivityProviders are injected into my ActivityMapper. So this may reduce to a Gin question: how do I get the user reference where it's needed? This seems to be similar to this SO question about global references in MVP.
Consider me a Gin newbie, this is my first attempt at using it. I'm guessing there is a "Gin way" to make this happen, but I don't know Gin well enough to know the best way to do this (if Gin should be used at all).
Much thanks.
Edit 1: Despite my best efforts searching SO for a similar question, I just found this question which is pretty much identical to mine (is the SO algorithm for finding "Related" links better than the search?). I'm thinking that the Gin answer by David is on the right track.
I don't think that an EventBus solution is possible. I'm following the Google guidelines which involve instantiating Activity at every Place change, so a single Event by itself will not suffice.
Something that I'm using on the server-side with Guice, and would work just as well on the client-side, is to bind to a custom Provider. In your case though, you'd have to make the provider a singleton and push the value into it from your RPC callback (rather than pulling it from some context).
You'd first need a specific provider:
#Singleton
public class CurrentUserProvider implements Provider<User> {
private User currentUser;
public User get() { return currentUser; }
public void setCurrentValue(User currentUser) {
this.currentUser = currentUser;
}
}
You'd bind User to the provider: bind(User.class).toProvider(CurrentUserProvider.class)
In your RPC callback you'd inject a CurrentUserProvider so you can setCurrentValue but everywhere else you'd inject Provider<User> to keep CurrentUserProvider as an implementation detail. For very short-lived objects, you could directly inject a User value rather than a Provider<User>.
If you need to notify objects of the value change, you could dispatch an event on the global event bus.
Alternately, you could always use the concrete CurrentUserProvider type (which wouldn't have to implement Provider anymore) and possibly make it a HasValueChangeHandlers so you could register listeners on it rather than on the event bus (but you'd have to clean-up after yourself in your activities' onStop and onCancel to avoid memory leaks, whereas it's taken care of automatically if you register handlers on the event bus in onStart).
(if you ask me, I'd rather go away with authenticating from within the app whenever possible)
I had similar requirements on a recent project.
When I get a reply from login (or logout) RPC I send a custom AuthenticationEvent on EventBus. All activities that are interested in this listen for this event. AuthenticationEvent has a reference to AppUser object which is null if user just logged out. AppUser contains all necessary data (privileges, groups, etc..) so that activities can inspect it and act upon it.
About global references: you can have a class with static methods providing data that you need. This class internally holds singleton references to needed instances. In my example I have static method AppUtils.getCurrentUser(). Internally it holds a reference to AppUser and also listens to AuthenticationEvent to set/reset this field.
As a side note: don't rely on client side to enforce access restrictions - you should separate your RPC servlets into two groups: public and private. Public can be accessed by anybody (this is basically login/logout RPC and some other public info RPC), while private RPC requires user to be authenticated. Access restrictions can be set per path/servlet: http://code.google.com/appengine/docs/java/config/webxml.html#Security_and_Authentication
Update:
As you noted, class with static methods is not advisable in this setup, because it is not replaceable and this prevents testing (which is the whole point of using GIN).
The solution is to inject a utility class holding globals (AppUtils) into activities that need the globals. AppUtils should be declared singleton in GIN configuration as one instance is enough for the whole app.
To use Provider or not is just a question if you want to delay the initialization of dependencies (AppUtil is dependency). Since AppUtils is a singleton for the whole app it makes no sense to have it lazy initialized.
Sometimes you will have a situation where you have multiple Activities shown on screen (in my case it was MenuBar and InfoBar). In this case, when user logs in you will need a way to notify them of the change. Use EventBus.