Difference between dispatch and emit in Flux/React Native - flux

I'm new in Flux/React Native.
I'm quite confused about dispatch vs emit using in Flux.
What is the main difference between them? And what happen when I use same Action Type in dispatch and emit.
For example:
Dispatcher.dispatch({
actionType: 'ACTION1'
});
SomeStore.emit('ACTION1');

In Flux, events are emitted by the store indicating a change in its state. This 'change' event is listened to by views. This will prompt a view to fetch new state from the store. Mind you, the event never contains payload / information about the new state. It is really just what it reads - an event.
Actions are slightly different. While they are indeed events, they are things that occur in our domain eg., Add item to cart. And they carry a payload that contains information about the action, eg.,
{
id: ‘add-item-to-cart’,
payload: {
cartId: 123,
itemId: 1234,
name: ‘Box of chocolates’,
quantity: 1
}
}
Actions are 'dispatched' from the views and the store(s) responds to the dispatch by possibly changing its state and emitting a 'change' event.
So basically:
A view dispatches an action with a payload (usually due to a user interaction) via the dispatcher
The store (which had previously registered itself with the dispatcher)
is notified of the action and uses the payload to change its state and emit an event.
The view (which had previously registered itself with the store) is notified of the change event which causes it to get the new state from the store and change itself.
So that's the difference. And about the question "use same Action Type in dispatch and emit", it doesn't really make sense, does it?
I suggest you read this blog post - http://blog.andrewray.me/flux-for-stupid-people/ (The title means no offence BTW :))
You already know this, but I'll say it again: A unidirectional data flow is central to the Flux pattern. That means data (not control) always flows in one direction.

Related

Where to make API call and how to structure actions

I've recently started migrating from ngrx to ngxs and had a design question of where I should be placing some of my calls.
In NGRX, I would create 3 actions for each interaction with an api. Something like:
GetEntities - to indicate that the initial api call was made
GetEntitiesSuccess - to indicate a successful return of the data
GetEntitiesFail - to indicate a unsuccessful return of the data
I would create an effect to watch for the GetEntities Action that actually called the API and handled the response by either calling the Success/Fail actions with the resultant payload.
In NGXS, do I make the api call from the store itself when the action occurs or is there some other NGXS object that I am supposed to use to handle those API calls and then handle the actions the same way I did in ngrx (by creating multiple actions per call)?
Most of the examples I have seen, and how I have used it is to make the API call from the action handler in the state, then when the API returns patch the state immediately.
Then after the patch call, you can dispatch an action to indicate success/failure if you need to. Something like this:
#Action(GetSomeData)
loadData({ patchState, dispatch}: StateContext<MyDataModel>, {payload}: GetSomeData) {
return this.myDataService.get(payload.id)
.pipe(
tap((data) => {
patchState({ data: data});
// optionally dispatch here
dispatch(new GetDataSuccess());
})
);
}
This q/a might also be useful Ngxs - Actions/state to load data from backend

Difference between "Signals" (js-signals) and "Observables" (mobx, mobx-react)?

Could they work together for a perfect states management and bidirectional data binding?
Mobx implements observable pattern in javascript. By using mobx and mobx-react, people can refer mobx observables in react and assign autorun, reaction, and comptued routines to them. Every time an observable changes its references relationship, autorun, reaction and computed routines fired.
This is really helpful when you developed a rich content application, say editor.
While js-signals works differently, a signal can register callbacks and its priority. When a component changes, a programmer have a choice to dispatch the signal to fire all associated callbacks (just like events)
Which pattern is better, could they work together smoothly?
Background
I am working on an editor which uses signals intensively. I also prefer to use observable patterns to manage states of the editor. My personal feelings, when the observable grows up (just like 200 global variables), it becomes hard to maintain.
I am appreciated for your thoughts. Developers who succeeded in using those techniques are welcomed.
js-signals is just an event emitter library and mobx is just a state/observer libary.
You can simply fire and handle events. as long as the handler wraps the changes of mobx State in a mobx.action. the changes in state are handled properly and react components are updated properly/observer events fired properly:
class Store {
#mobx.observable name = "test"
}
var store = new Store();
//custom object that dispatch a `started` signal
var myObject = {
started : new signals.Signal()
};
function onStarted(name){
mobx.runInAction(() => {
store.name = name;
});
}
myObject.started.add(onStarted); //add listener
mobx.observe(store,"name",change=> {
myObject.started.dispatch(change.name+'x'); //woops now we have an infinite loop!
});
myObject.started.dispatch('foo'); //dispatch signal passing custom parameters
// myObject.started.remove(onStarted); //remove a single listener

Notifying clients from (boxed) Syncfusion Ajax call

I'm trying to integrate the schedule component from Syncfusion. The component has a URL adaptor to connect to the controller; GetData() and Batch() for Crud Operations. Batch has a payload indicating what actions to perform. At the end, the Batch method would requery the database and send data identical to GetData() back.
Unfortunately, there is no built-in method to notify clients of anything going wrong - whether there is an exception, server-side validation kicks in or similar.
What I'd like to do is to add a placeholder outside the compentent to receive and display server messages (be it a notification popup, a or whatever.
Since I can't influence the Ajax call itself, I was wondering if I had to get started with SignalR (still in beta for .Net Core 2 as far as I know), or if I may have missed something more obvious? I have read a lot about push notifications etc - but these are not quite what I'm after, it'd be slightly over the top I think.
To summarise, let's say I have
<div id="messages"></div>
<div id="component">HereGoesTheScheduleWhichICantDoMuchWith</div>
Now in the Batch() method, it would be great to call a SendMessage("Sorry,you can't do this") - the text of which would ideally then appear in the messages-div.
How would you go about this?
I have now solved this, using SignalR (currently 1.0.0-alpha2-final) and for a nice view on the Client, PNotify.
Presently, it only works if the client is authenticated, if it needs to work anonymously you'd need to figure out a way to track SignalR's connection id.
On the page with the Syncfusion Schedule component, I connect to SignalR.
let connection = new signalR.HubConnection("/signalr", { transport: signalR.TransportType.ServerSentEvents });
connection.on("Notify",
(title, message) => {
new PNotify({
title: title,
text: message
});
});
connection.start();
The Hub (SignalRHub : Hub) creates a notification group for the user connecting:
public override Task OnConnectedAsync()
{
Groups.AddAsync(Context.ConnectionId, Context.User.Identity.Name);
return base.OnConnectedAsync();
}
The associated controller gets IHubContext<SignalRHub> signalRHub injected.
Now in the Batch-Method for the Syncfusion component, which returns Json and can't itself carry messages or notifications, you can notify the user:
_signalRHub.Clients.Group(User.Identity.Name).InvokeAsync("Notify", "A title", "A message");
In my particular case, I'm sending over an object to control layout, animation and popup duration for PNotify (e.g. longer for an exception to allow copy/paste etc) - as you please. Returning an object could be done using:
_signalRHub.Clients.Group(User.Identity.Name).InvokeAsync("Notify", JsonConvert.SerializeObject(new { title = "Some Title", message = "notification", type = "notice"}););
Obviously, connection.on("Notify"... needs to be changed accordingly.
I hope this is clear enough and might help someone else.

Flux Store and actions with temporary data

Note: This is a follow-up question of https://stackoverflow.com/questions/32536037/flux-store-collection-by-criteria-vs-single-item but it is independent to understand and answer.
Imagine we have an application for managing (CRUD) Tasks. One operation is a Task editing.
First the edit view loads the Task using an action creator that asynchronously fetches it from the server and dispatches TASK_LOAD_SUCCESS event together with the Task payload. Next a Task Store stores the Task and emits a change event so that the edit view can read it and fill the form.
When the user submits the form the changes should be saved and the edit view should be closed.
On the submit the edit view tells action creator to asynchronously save the Task. On AJAX success the TASK_SAVE_SUCCESS is dispatched (to the Task store).
Q1: What should the Task Store do? Should it update its internal flag that a task has been saved then emit the change event and then the view should read that flag from the store and close itself if it is true?
Q2: Should the Store find the Task in the collection of the previously loaded Tasks and update it there? Other Tasks in the collection will remain stale (see Q2 in https://stackoverflow.com/questions/32536037/flux-store-collection-by-criteria-vs-single-item).
Q3: What if we edit the Task again? The Store still has the flag that the Task has been successfully saved and it closes itself immediately. But it was from the previous save. How to deal with it?
Simmilar problem arises if we want to delete a Task. We use an optimistic locking and therefore we must first read the Task from the server then show the confirmation dialog and finally delete the Task on the server (providing ETag from the first read).
Q4: How to use the store to signal that the Task has been loaded for the deletion? During this AJAX call there might another asynchronous read operation become complete and it would clash with this one. Should there be a separate Store for a Task deletion?
Q5: This is same as Q1. After the deletion how to tell the view that it is done so it can close the confirmation dialog?
Q1-Q3: you may store an edit_timestamp in TaskStore and open_timestamp for confirmation dialog. On emitChange you may compare if edit_timestamp > open_timestamp.
Q4: you may cache request Promise for each taskId on fetch request. So instead doing the same request twice (read/delete fetch for the same taskId), you may subscribe on the existed Promise. That allow you to keep only the single instance of task, and I hope avoid Q5 problems:
//To imagine how to arrange promise-based async interaction you may look here http://mjw56.github.io/handling-asynchronous-data-flow-in-flux/index.html
var promises = {};
//Returns Promise
var asyncGetCall = function(taskId) {...}
var getTaskForDelete, getTaskForRead;
getTaskForDelete = getTaskForRead = function(taskId) {
if (!promises[taskId]) {
promises[taskId] = asyncGetCall(taskId);
}
return promises[taskId];
}
getTaskForDelete(10).then(function() {...}); //do asyncGetCall
getTaskForRead(10).then(function() {...}); // do nothing, wait for the first req results

Relation between command handlers, aggregates, the repository and the event store in CQRS

I'd like to understand some details of the relations between command handlers, aggregates, the repository and the event store in CQRS-based systems.
What I've understood so far:
Command handlers receive commands from the bus. They are responsible for loading the appropriate aggregate from the repository and call the domain logic on the aggregate. Once finished, they remove the command from the bus.
An aggregate provides behavior and an internal state. State is never public. The only way to change state is by using the behavior. The methods that model this behavior create events from the command's properties, and apply these events to the aggregate, which in turn call an event handlers that sets the internal state accordingly.
The repository simply allows loading aggregates on a given ID, and adding new aggregates. Basically, the repository connects the domain to the event store.
The event store, last but not least, is responsible for storing events to a database (or whatever storage is used), and reloading these events as a so-called event stream.
So far, so good.
Now there are some issues that I did not yet get:
If a command handler is to call behavior on a yet existing aggregate, everything is quite easy. The command handler gets a reference to the repository, calls its loadById method and the aggregate is returned. But what does the command handler do when there is no aggregate yet, but one should be created? From my understanding the aggregate should later-on be rebuilt using the events. This means that creation of the aggregate is done in reply to a fooCreated event. But to be able to store any event (including the fooCreated one), I need an aggregate. So this looks to me like a chicken-and-egg problem: I can not create the aggregate without the event, but the only component that should create events is the aggregate. So basically it comes down to: How do I create new aggregates, who does what?
When an aggregate triggers an event, an internal event handler responses to it (typically by being called via an apply method) and changes the aggregate's state. How is this event handed over to the repository? Who originates the "please send the new events to the repository / event store" action? The aggregate itself? The repository by watching the aggregate? Someone else who is subscribed to the internal events? ...?
Last but not least I have a problem understanding the concept of an event stream correctly: In my imagination, it's simply something like an ordered list of events. What's of importance is that it's "ordered". Is this right?
The following is based on my own experience and my experiments with various frameworks like Lokad.CQRS, NCQRS, etc. I'm sure there are multiple ways to handle this. I'll post what makes most sense to me.
1. Aggregate Creation:
Every time a command handler needs an aggregate, it uses a repository. The repository retrieves the respective list of events from the event store and calls an overloaded constructor, injecting the events
var stream = eventStore.LoadStream(id)
var User = new User(stream)
If the aggregate didn't exist before, the stream will be empty and the newly created object will be in it's original state. You might want to make sure that in this state only a few commands are allowed to bring the aggregate to life, e.g. User.Create().
2. Storage of new Events
Command handling happens inside a Unit of Work. During command execution every resulting event will be added to a list inside the aggregate (User.Changes). Once execution is finished, the changes will be appended to the event store. In the example below this happens in the following line:
store.AppendToStream(cmd.UserId, stream.Version, user.Changes)
3. Order of Events
Just imagine what would happen, if two subsequent CustomerMoved events are replayed in the wrong order.
An Example
I'll try to illustrate the with a piece of pseudo-code (I deliberately left repository concerns inside the command handler to show what would happen behind the scenes):
Application Service:
UserCommandHandler
Handle(CreateUser cmd)
stream = store.LoadStream(cmd.UserId)
user = new User(stream.Events)
user.Create(cmd.UserName, ...)
store.AppendToStream(cmd.UserId, stream.Version, user.Changes)
Handle(BlockUser cmd)
stream = store.LoadStream(cmd.UserId)
user = new User(stream.Events)
user.Block(string reason)
store.AppendToStream(cmd.UserId, stream.Version, user.Changes)
Aggregate:
User
created = false
blocked = false
Changes = new List<Event>
ctor(eventStream)
isNewEvent = false
foreach (event in eventStream)
this.Apply(event, isNewEvent)
Create(userName, ...)
if (this.created) throw "User already exists"
isNewEvent = true
this.Apply(new UserCreated(...), isNewEvent)
Block(reason)
if (!this.created) throw "No such user"
if (this.blocked) throw "User is already blocked"
isNewEvent = true
this.Apply(new UserBlocked(...), isNewEvent)
Apply(userCreatedEvent, isNewEvent)
this.created = true
if (isNewEvent) this.Changes.Add(userCreatedEvent)
Apply(userBlockedEvent, isNewEvent)
this.blocked = true
if (isNewEvent) this.Changes.Add(userBlockedEvent)
Update:
As a side note: Yves' answer reminded me of an interesting article by Udi Dahan from a couple of years ago:
Don’t Create Aggregate Roots
A small variation on Dennis excellent answer:
When dealing with "creational" use cases (i.e. that should spin off new aggregates), try to find another aggregate or factory you can move that responsibility to. This does not conflict with having a ctor that takes events to hydrate (or any other mechanism to rehydrate for that matter). Sometimes the factory is just a static method (good for "context"/"intent" capturing), sometimes it's an instance method of another aggregate (good place for "data" inheritance), sometimes it's an explicit factory object (good place for "complex" creation logic).
I like to provide an explicit GetChanges() method on my aggregate that returns the internal list as an array. If my aggregate is to stay in memory beyond one execution, I also add an AcceptChanges() method to indicate the internal list should be cleared (typically called after things were flushed to the event store). You can use either a pull (GetChanges/Changes) or push (think .net event or IObservable) based model here. Much depends on the transactional semantics, tech, needs, etc ...
Your eventstream is a linked list. Each revision (event/changeset) pointing to the previous one (a.k.a. the parent). Your eventstream is a sequence of events/changes that happened to a specific aggregate. The order is only to be guaranteed within the aggregate boundary.
I almost agree with yves-reynhout and dennis-traub but I want to show you how I do this. I want to strip my aggregates of the responsibility to apply the events on themselves or to re-hydrate themselves; otherwise there is a lot of code duplication: every aggregate constructor will look the same:
UserAggregate:
ctor(eventStream)
foreach (event in eventStream)
this.Apply(event)
OrderAggregate:
ctor(eventStream)
foreach (event in eventStream)
this.Apply(event)
ProfileAggregate:
ctor(eventStream)
foreach (event in eventStream)
this.Apply(event)
Those responsibilities could be left to the command dispatcher. The command is handled directly by the aggregate.
Command dispatcher class
dispatchCommand(command) method:
newEvents = ConcurentProofFunctionCaller.executeFunctionUntilSucceeds(tryToDispatchCommand)
EventDispatcher.dispatchEvents(newEvents)
tryToDispatchCommand(command) method:
aggregateClass = CommandSubscriber.getAggregateClassForCommand(command)
aggregate = AggregateRepository.loadAggregate(aggregateClass, command.getAggregateId())
newEvents = CommandApplier.applyCommandOnAggregate(aggregate, command)
AggregateRepository.saveAggregate(command.getAggregateId(), aggregate, newEvents)
ConcurentProofFunctionCaller class
executeFunctionUntilSucceeds(pureFunction) method:
do this n times
try
call result=pureFunction()
return result
catch(ConcurentWriteException)
continue
throw TooManyRetries
AggregateRepository class
loadAggregate(aggregateClass, aggregateId) method:
aggregate = new aggregateClass
priorEvents = EventStore.loadEvents()
this.applyEventsOnAggregate(aggregate, priorEvents)
saveAggregate(aggregateId, aggregate, newEvents)
this.applyEventsOnAggregate(aggregate, newEvents)
EventStore.saveEventsForAggregate(aggregateId, newEvents, priorEvents.version)
SomeAggregate class
handleCommand1(command1) method:
return new SomeEvent or throw someException BUT don't change state!
applySomeEvent(SomeEvent) method:
changeStateSomehow() and not throw any exception and don't return anything!
Keep in mind that this is pseudo code projected from a PHP application; the real code should have things injected and other responsibilities refactored out in other classes. The ideea is to keep aggregates as clean as possible and avoid code duplication.
Some important aspects about aggregates:
command handlers should not change state; they yield events or
throw exceptions
event applies should not throw any exception and should not return anything; they only change internal state
An open-source PHP implementation of this could be found here.

Resources