meteorjs iron-router event for route exited - events

Does iron-router have any events I can tie into for when the user exits a route? In my example, I have a setTimeout() call that I start when the route is first loaded. But when they leave that route (by whatever means), I want to clearTimeout() so it doesn't keep firing after they've left that route.

well, I guess it helps if I RTFM. All I had to do was define 'onStop' in my RouteController. duh, of course it's that simple.

Related

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.

How to use Event::queue in laravel?

I've read a lot about Event::queue but I just cant get my head around it, so i have something like:
Event::listen('send_notification');
and in the controller I use
Event::fire('send_notification');
But because this takes sometime before sending the user to somewhere else, I instead want to use
Event::queue('send_notification');
To fire the event after the user has been redirected, but I don't know how.
(In the app/config/app.php i have the queue driver set to sync)
EDIT:
a small note about firing the event ,u can do all ur work just like normal ,and add all the Event::flush() as a filter ,then just call that filter through ->after() or afterFilter().
First, let me make something clear. Event::queue has nothing to do with the Queue facade and the query driver in the config. It won't enable you to fire the event after the request has happened.
But you can delay the firing of an event and therefore "prepare" it.
The usage is pretty basic. Obviously you need one or many Event::listen (well it works without them but makes no sense at all)
Event::listen('send_notification', function($text){
// send notification
});
Now we queue the event:
Event::queue('send_notification', array('Hello World'));
And finally, fire it by calling flush
Event::flush('send_notification');
In your comment you asked about flushing multiple events at once. Unfortunately that's not really possible. You have to call flush() multiple times
Event::flush('send_notification');
Event::flush('foo');
Event::flush('bar');
If you have a lot of events to flush you might need to think about your architecture and if it's possible to combine some of those into one event with multiple listeners.
Flushing the Event after redirect
Event::queue can't be used to fire an event after the request lifecycle has ended. You have to use "real" queues for that.

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

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({...});
}

Iron-router route 'loaded' event

I'm a bit new to iron-router but I'm curious if there's an event handler I can define for after a route is loaded. If I attempt to call Router.current().data() in Meteor.startup, I get 'undefined' for Router.current(). I'd like to know the 'right' way to start doing things once the data is loaded in that route...
The code you're using is fine - Router.current().data().
The issue is that there is a race condition here. There are two things going on here, Meteor.startup may run before or after the router has decided what route its on. If it runs before the route has loaded, Router.current() would be null.
You might want to consider putting your code in your route's onAfterAction instead. This way it will also run on the correct page too. Router.current().data() would give back the wrong data on a different route.
Another thing to keep in mind is with Meteor you download the html, js and css first & have it load. Then the data comes after, so when you're looking for data when the page loads you have to wait for it first, otherwise you wont have anything.
Iron Router also has a hook called onData which reactively reruns when the corresponding route's data() changes. You can use this to ensure you have the data available and have it run after everything has loaded properly.

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