Flux Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch - flux

My code
https://gist.github.com/ButuzGOL/707d1605f63eef55e4af
So when I get sign-in success callback I want to make redirect,
redirect works through dispatcher too.
And I am getting Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
Is there any hack to call action in the middle ?

I don't see where in the gist that you posted you are doing the redirect. I only see the AUTH_SIGNIN and AUTH_SIGNIN_SUCCESS actions, and they look pretty straightforward.
But no, there is no hack to create an action in the middle of a dispatch, and this is by design. Actions are not supposed to be things that cause a change. They are supposed to be like a newspaper that informs the application of a change in the outside world, and then the application responds to that news. The stores cause changes in themselves. Actions just inform them.
If you have this error, then you need to back up and look at how you're handling the original action. Most often, you can set up your application to respond to the original action, accomplish everything you need to do, and avoid trying to create a second action.

You can make it work by "scheduling" the next action instead of calling it directly, here is an example code:
// instead of doing this
Dispatcher.dispatch(...);
// go like this
setTimeout(function() {
Dispatcher.dispatch(...);
}, 1);
This will cause your next dispatch to be called later out of the current dispatch process, and no error will happen.
If your dispatch code is on a callback any kind of other async operation that will work as well (for example in a response for an Ajax request).
I'm using this style to make some forms respond to generic data here and I'm facing no issue, at least the way I'm using it.

you can user the "defer" option in the dispatcher.
In your case it would be like:
Dispatcher.dispatch.defer(...);

You can check if the dispatcher is dispatching, such as:
if(!MyDispatcher.isDispatching()) {
MyDispatcher.dispatch({...});
}

Related

Cancel currently running function/goroutine

I'm using gin-gonic as HTTP handler. I want to prerender some graphical resources after my users make POST request. For this, I put a middleware that assign a function (with a timer inside) to a map[string]func() and call this function directly after assignation.
The problem is, when the user make two subsequent request, the function is called twice.
Is there any way to clear function ref and/or his currently running call like a clearInterval or clearTimeout in Javascript ?
Thanks
No; whatever function you've scheduled to run as a goroutine needs to either return or call runtime.Goexit.
If you're looking for a way to build cancellation into your worker, Go provides a primitive to handle that, which is already part of any HTTP request - contexts. Check out these articles from the Go blog:
Concurrency Patterns: Context
Pipelines and cancellation
I suppose your rendering function is calling into a library, so you don't have control over the code where the bulk of the time is spent. If you do have such control, just pass a channel into the goroutine, periodically check if the channel is closed, and just return from the goroutine if that happens.
But actually I would recommend a different, and simpler, solution: keep track (in a map) of the file names (or hashes) of the files that are currently being processed, and check that map before launching a second one.

Is it a good practice to call action within another action (in flux)

I have an action as follows:
SomeActions.doAction1(){
//..dispatch event "started"...
//...do some process....
FewActions.doAnotherAction(); //CAN WE DO THIS
//...do something more....
//..dispatch event "completed"..
}
While the above works with no problems, just wondering, if it is valid according to flux pattern/standard or is there a better way.
Also, I guess calling Actions from Stores are a bad idea. Correct me if I am wrong.
Yes, calling an Action within another Action is a bad practice. Actions should be atomic; all changes in the Stores should be in response to a single action. They should describe one thing that happened in the real world: the user clicked on a button, the server responded with data, the screen refreshed, etc.
Most people get confused by Actions when they are thinking about them as imperative instructions (first do A, then do B) instead of descriptions of what happened and the starting point for reactive processes.
This is why I recommend to people that they name their Action types in the past tense: BUTTON_CLICKED. This reminds the programmer of the fundamentally externally-driven, descriptive nature of Actions.
Actions are like a newspaper that gets delivered to all the stores, describing what happened.
Calling Actions from Stores is almost always the wrong thing to do. I can only think of one exception: when the Store responds to the first Action by starting up an asynchronous process. When the async process completes, you want to fire off a second Action. This is the case with a XHR call to the server. But the better way is to put the XHR handling code into a Utils module. The store can then respond to the first Action by calling a method in the Utils module, and then the Utils module has the code to call the second Action when the server response comes back.

Error Handler with Flux

I have a React.js application that I am refactoring to use the Flux architecture, and am struggling to figure out how error handling should work while sticking to the Flux pattern.
Currently when errors are encountered, a jQuery event 'AppError' is triggered and a generic Error Handling helper that subscribes to this event puts a Flash message on the user's screen, logs to the console, and reports it via an API call. What is nice is I can trigger an error for any reason from any part of the application and have it handled in a consistant way.
I can't seem to figure out how to apply a similar paradigm with the Flux architecture. Here are the two particular scenarios I'm struggling with.
1) An API call fails
All of my API calls are made from action creators and I use a promise to dispatch an error event (IE 'LOAD_TODOS_FAILED') on failure. The store sees this event and updates it's state accordingly, but I still dont have my generic error behavior from my the previous iteration (notifications, etc).
Possible resolution:
I could create an ErrorStore that binds to the 'LOAD_TODOS_FAILED' action, but that means every time I have a new type of error, I need to explicitly add that action to the ErrorStore, instead of having all errors be automatically handled.
2) Store receives an unexpected action
This is the one I'm really confused about. I want to handle cases when an action is dispatched to a Store that does not make sense given the Store's current state. I can handle the error within the Store to clean up the state, but still may want to trigger an error that something unexpected happen.
Possible resolutions:
Dispatch a new action from the store indicating the error.
I believe Stores are not suppose to dispatch actions (let me know if I'm wrong), and I still have the same issue as with an API error above.
Create a ControllerView for Error Handling that subscribes to every Store
I could define an errors property on every store, then have a View watching every Store and only act on the errors property. When the errors property is not null, it could dispatch new actions, etc. The disadvantages are that I need to remember to add every Store to this view whenever new ones are created, and every store has to have an error property that behaves the same way. It also does nothing to address API call failures.
Does anyone have a suggested approach for a generic Error Handler that fits into the Flux architecture?
TL;DR
I need to handle errors in most Action Creators and Stores. How do I setup consistent error handling that will occur for any type of generic error?
API call fails
If you want to avoid listing every error action in the ErrorStore, you could have a generic APP_ERROR action, and have properties of that action that describe it in more detail. Then your other stores would simply need to examine those properties to see if the action is relevant to them. There is no rule that the registered callback in the stores needs to be focused on the action's type, or only on the type -- it's just often the most convenient and consistent way of determining if an action is relevant.
Store receives an unexpected action
Don't issue a new action in response to an action. This results in a dispatch-within-a-dispatch error, and would lead to cascading updates. Instead, determine what action should be dispatched ahead of time. You can query the stores before issuing an action, if that helps.
Your second solution sounds good, but the dangerous thing you mentioned is "When the errors property is not null, it could dispatch new actions, etc" -- again, you don't want to issue actions in response to other actions. That is the path of pain that Flux seeks to avoid. Your new controller-view would simply get the values from the stores and respond by presenting the correct view.

ExtJS 4 - How to check if all current ajax requests are completed and then perform an action?

I have a page which fires Ajax requests for validations at server side. I need to perform an action when all the ajax requests have finished loading or are completed.
For this, I am using Ext.Ajax.isLoading() in a recursive function in following way:
function chechValid(){
if(Ext.Ajax.isLoading()){
checkValid();
}else{
//Code for Action 1
}
}//EOF
checkValid();
//Code for Action 2
The problem is that when I do this, browsers give the following errors:
Mozill FF - too much recursions
IE - Stack overflow at line:18134
If this recursion is a heavy thing for the browsers, then how to perform a task when all the Ajax requests have finished loading?
Using delay is not what I want as, if delay is used then browser begins executing the other code (like 'Code for Action 2' as shared above) which is not what is expected.
The main aim is that the browser shouldn't execute anything unless all the Ajax requests are complete and once completed then it should perform a particular action.
Any suggestions/help on this one?
Thanks in Advance.
PS: Using ExtJs 4.0.7
(Updated)More Detail about the actual situation:-
Here is brief description of the situtaion being faced - There is a form, in which I need to perform server side validations on various fields. I am doing so by firing an ajax request on blur event. Depending upon the server response of validation Ajax fired on blur, fields are marked invalid and form submission is not allowed. (Avoiding 'change' event as that causes alot of overhead on server due to high number of Ajas requests and also leads to fluctuating effects on a field when response from various such Ajax requests are received).
Things are working fine except in one case - when user modifies the value of a field and instead of 'tab'bing out from the field she directly clicks at the save button. In such a case, though, the blur event gets fired but the processing of 'Save' doesn't wait for Ajax Validation response and submits the form. Thus, I somehow need to check if Ajax requests have finihed loading and the process the saving of form. requestComplete would unfortunately not serve the purpose here. And if try using the recursion, then of course, the browser is hung due to high usage of resources. Same case occurs if I try using a pause script work around ( as shared here - Javascript Sleep).
Any possible workaround for this one?
TIA
Your method will lead to infinite recursion.
A better way is to register a callback function in Ext.Ajax.requestcomplete, something like this (not tested):
Ext.Ajax.on('requestcomplete', function(conn, response, options) {
if (!Ext.Ajax.isLoading()) {
//your action...
}
}
};
Unless I am misunderstanding the issue couldn't you create a couple of globals. I know globals are bad, but in this case it will save you quite a bit of headache. One global would be "formReady" and initially set it to false, the other would be "ajaxActive" and set to false. You would also add an onSubmit method that would validate that "formReady" was true and if not alert the user that validation was occurring (or you could set a timeout for form submission again and have a second validation that checks to see if "ajaxActive" is true). When the AJAX call is made it would set the variable "ajaxActive" to true and once complete would set formReady to true. You could also potentially resubmit the form automatically if the response from the AJAX was that the form was good.
Ext.Ajax.request() returns a transaction object when you call it, which is unique and allows you to recognise and abort specific Ajax requests.
By just calling Ext.Ajax.isLoading() without a specified transaction object, it defaults to the last request, which is why you have to call it recursively at the moment.
If it were me, I'd create an array of these transaction objects as you fire them off, and pass each of those in as optional parameters to the Ext.Ajax.isLoading() function to check if a particular request has finished. If it has, you can remove that transaction object from the array, and only progress with the save when your array is empty.
This would get round your recursion problem, since you've always got a finite number of requests that you're waiting on.
if (Object.keys(Ext.Ajax.requests).length === 0) console.log("No active requests");

Cancel controller action from Initialize()

I have come across a scenario where I have some initialization code on my conrtoller, which might identify an invalid state which will demand some user interaction.
There for, I want to redirect the customer to another page/action if that occurs. Since I don't want the initial action to run if I hit this invalid state, I want to cancel the whole request including the action.
Is this possible? We have figured out that one way to solve it is to use a Filter which reads out from Context.Items if it should cancel the action, but is there another, easier way?
I started reading this and immediately thought "Context and Filter" :-)
I think that is the cleanest way to do it... That said, you could also do
Context.UnderlyingContext.Response.Redirect("someotherurl");
Which internally throws a ThreadAbortException so it skips all other code.

Resources