I have the following use-case. I use NgRx Store/Effects and I need to send a request to my back-end service.
Request is initiated in my component, then dispatch to NgRx Effect and then sent to my back-end service.
But I need to attach a piece of state to my Http request. So far I see two ways of doing it:
1) Select state from Store in the component and include into Action as payload
2) Inject Store into Effect and select piece of the state from Store in the specific effect
What is the suggested way from NgRx-driven point of view?
Personally I would opt for option one if possible. Because it's easier to understand with the benefit that it's easy to test.
There are some times where this isn't possible or where it would cause too much overhead, if that's the case I use a withLatestFrom(storeSelector) inside an effect.
Related
I struggle finding the right way to mutate my state in an ngrx application as the state is rather complex and depending on many factors. This Question is not about doing one piece of code correct but more about how to design such a software in general, what are doe's and don'ts when finding some hacky solutions and workarounds.
The app 'evolved' by time and i wan't to share this process in an abstracted way to make my point clear:
Stage 1
State contains Entities. Those represent nodes in a tree and are linked by ids. Modifying or adding an entity requires a check about the type of nodes the new/modified ones should be connected with. Also it might be that upon modifying a node, other nodes had to be updated.
The solution was: create functions that do the job. Call them right in the reducer so everything is always up to date and synchronus when used (there are services that might modify state).
Stage 2
A configuration is added to the state having an impact on the way the automatically modifyed nodes are modifyed/created. This configuration is saved in it's own state right under the root state.
The solution:
1) Modify the actions to also take the required data from the configuration.
2) Modify the places where the actions are created/dispatched (add some ugly
this.state.select(fromRoot.getX)
.first()
.(subscribe(element => {this.state.dispatch(new Action({...old_payload, newPayload: element}))})
wrapper around the dispatch-calls)
3) modify the functions doing the node-modification and
4) adding the argument-passing to the function calls inside the reducer
Stage 3
Now i'am asked to again add another configuration to the process, also retrived by the backend and also saved in another state right under the root state
State now looks like:
root
|__nodes
|__config_1
|__config_2
i was just about to repeat the steps as in stage 2 but the actions get really ig with all the data passed in and functions have to carry around a lot of data. This seems to be wrong, when i actually dispatch the action on the state containing all the needed info.
How can i handle this correct?
Some ideasi already had:
use Effects: they are able to get everything from state they need and can create everything - so i only need to dispatch an action with only the actions payload, the effect then can grab everything from the state it needs. I don't like this idea because it triggers asynchronus tasks to modify the state and add not-state-changing actions.
use a service: with a service holding state it would be much like with effects but without using actions to just create asynchronus calls which then dispatch the actions that relly change state.
do all the stuffi n the component: at the moment the components are kept pretty simple when it comes to changing state as i prefer the idea that actions carry as little data as possible, since reducers can access the state to get theyr data - but this is where the problem occus, this time i can't get hands on the data i need.
I'm starting to read up on Redux and I like what I see so far. There is one area of concern that I have and it's async actions. I've seen how sagas, thunk, and others help in this area but I feel like I'm missing something.
I'm a fan of using FSMs to handle application logic and prevent things from getting out of sync, so coming to redux and not seeing something like this is a bit jarring to me.
I have an example in my mind that I keep coming back to that I want redux (or some plugin) to solve:
I have a login form. When the user presses login, an async call is made to a server. This is fine. But if the user presses login again, then another call is made to the server and the application state is now out of sync. I could add a state property that defines loggingIn, but this only works in this example.
Lets say I have a much bigger dependency. Lets say when a user logs in, an action is done to preload some data. And that data contains a preflight of more data to load. This now introduces a lot of if/else conditional logic and adds more information to the state. In a FSM, I would define multiple concurrent states for theses. Such as user:loggedIn, manifest:fetched, pageData:fetched. And each state would be a child of each other: user:loggedIn -> manifest:fetched -> pageData:fetched. So if a request was made to login, or refetch data, an error would be thrown because it's not a valid handler for the current state. How does one accomplish such complexity in Redux? Is it even possible?
Another example. Stemming off the Reddit API example. Lets say a user goes to a reddit post. I don't want the user to be able to submit a comment on the post before it's even loaded. I know this could be handled on the UI side with conditionals and such, but that seems really archaic.
I really appreciate any guidance.
Thanks!
Is there any tool out there which can generate sequecne diagrams from redux actions calls ? Basically i have written a client side applciation using javascript, Redux and Angular and want to generate a sequence diagram
The short answer: I didn't see anything like that until now.
But it should be relatively easy to implement, here are some of my thoughts:
With Redux you already should have most of the stuff in your hand:
The communication partners are various web components which are triggering actions and/or subscribing to the store.
A request between a communication partners is represented by a dispatched action.
Each time an action has been dispatched we persist (depending on the application perhaps as part of the state) the following information that is later needed to draw a sequence diagram:
the communication partner that triggered the dispatch of the action (a property within the action)
the action type
the receivers, i.e. the communication partner(s) that is(are) interested in the changes that were triggered by the action. This could perhaps come from additional "acknowledgement" actions triggered by the receivers or from a static configuration that contains a mapping of which subscribers are interested in which parts of the state.
I am writing an Adobe AIR application using PureMVC.
Imagine that I have an page-based application view ( using ViewStack ), and user is navigating through this pages in some way ( like clicking the button or whatever ).
Now for example I have an Account Infromation page which when instantiated or showed again needs to load the data from WebService ( for example email, account balance and username ), and when the data is returned I want to show it on my Account Information page in the proper labels.
The problem is when I will execute this three Web Calls, each of them will return different resultEvent at different time. I am wondering what is the best way to get the information that ALL of the service calls returned results, so I know that I can finally show all the results at once ( and maybe before this happens play some loading screen ).
I really don't know much about PureMVC, but the as3commons-async library is great for managing async calls and should work just fine in any framework-setup
http://as3commons.org/as3-commons-async/
In your case, you could create 3 classes implementing IOperation or IAsyncCommand (depending on if you plan to execute the operations immediately or deferred) encapsulating your RPCs.
After that is done you simply create a new CompositeCommand and add the operations to its queue.
When all is done, CompositeCommand will fire an OperationEvent.COMPLETE
BTW, the library even includes some pre-implemented common Flex Operations, such as HTTPRequest, when you download the as3commons-asyc-flex package as well.
I would do it in this way:
Create a proxy for each of three information entities (EMailProxy, BalanceProxy, UsernameProxy);
Create a delegate class which handles the interaction with your WebService (something like "public class WSConnector implements IResponder{...}"), which is used by the proxies to call the end ws-methods;
Create a proxy which coordinates all the three results (CoordProxy);
Choose a mediator which will coordinate all the three calls (for example it could be done by your ApplicationMediator);
Create notification constants for all proxy results (GET_EMAIL_RESULT, GET_BALANCE_RESULT, GET_USERNAME_RESULT, COORD_RESULT);
Let the ApplicationMediator get all 4 notifications;
it is important that you should not only wait for all three results but also be ready for some errors and their interpretation. That is why a simple counter could be too weak.
The overall workflow could look like this:
The user initiates the process;
Some mediator gets an event from your GUI-component and sends a notification like DO_TRIPLECALL;
The ApplicationMediator catches this notification, drops the state of the CoordProxy and calls all 3 methods from your proxies (getEMail, getBalance, getUsername).
The responses are coming asynchronously. Each proxy gets its response from the delegate, changes its own data object and sends an appropriate notification.
The ApplicationMediator catches those notifications and changes the state of the CoordProxy. When all three responses are there (may be not all are successful) the CoordProxy sends a notification with the overall result.
I know it is not the best approach to do such an interaction through mediators. The initial idea was to use commands for all "business logic" decisions. But it can be too boring to create the bureaucracy.
I hope it can help you. I would be glad to know your solution and discuss it here.
Thinking about REST, it's relatively easy to map HTTP methods to CRUD actions: POST for create, GET for read, etc. But what about "fire and forget" actions? What HTTP method would best represent a fire and forget action such as triggering a batch job (in which no response is sent back to the caller)?
POST would spring to mind, but I think GET is also an appropriate method because 99% of the time you only supply a bunch of parameters to these types of actions. What do you think?
POST would spring to mind, but I think GET is a more appropriate method because 99% of the time you only supply a bunch of parameters to these types of actions. What do you think?
External State
I think that the number of parameters you use has nothing to do with the verb you use. The key issue is are you changing externally visible state?
BatchJob Resources
In your example, if the batch job does not affect the externally visible state of any object then you could implement it as a batch job. However you could model your batch job as a resource with an associated resource container.
You could use a Post to create a new BatchJob resource and allow the user to do a GET to see the progress of the job so far. You could do a GET on the resource container to list all of the running batch jobs, possibly calling DELETE to kill one.
You should use POST if your request modifies data, and GET if it only reads it.
Since your request is "fire and forget", I guess that it's modifying data, so use POST.
I think in the general case we might well supply various payload parameters, and these plausibly might exceed what's possible with GET, so POST is quite reasonable - the action of starting a job doesn't to me fit well with GET sematics.
One thought, might not the action actually return a response:
a). No, sir, that's an impossible request we can't start your job.
b). Understood, your job reference is 93.
If you're concerned at that level, perhaps HEAD is the HTTP method you want; it's identical to GET, with the stipulation that the response body is empty. That sounds to me spot-on to what you're asking for?
I'm bringing this question back from the dead to offer a different point of view.
Now that CORS is prevalent, the choice between using GET or POST becomes a matter of if you want anyone who knows your API URI to be able to trigger the batch job (GET), or if you want to restrict the origin of the request to prevent any Joe with a computer from triggering the job (POST).