I'm writing a realtime updating graph using Angular2. My graph is being updated through data coming via an http observable, and a setInterval command.
A weird thing I've noticed is that, when I route through angular to a different view on my app, the setInterval command on the previous component does not stop, causing the server for unnecessary load.
What would be the correct method to stop setInterval http requests on route changes in Angular2?
Any help would appreciated.
Events are managed very differently by browsers, basically they are processed by Event loop.
The browser has inner loop, called Event Loop, which checks the queue
and processes events, executes functions etc.
So whenever you add any asynchronous event like setTimeout/setInterval, they gets added to Event Loop with their handlers.
Basically whenever you wanted to stop/de-register those asynchronous event, you need to de-register them manually. Like here you need to call clearInterval method with that setInterval object reference, then only it will remove that async event from Event Loop.
You could use ngOnDestroy life-cycle hook where you can have your stuff before destroying your component.
//hook gets called before Component get destroyed or you can say disposed.
ngOnDestroy(){
clearInterval(intervalReference)
}
Extra stuff(Comparing with Angular 1)
The same kind of problem you can see in any Javascript Framework. In Angular 1 there is way to handle such kind of situation(I'm adding this stuff so that anyone from Angular 1 background can easily get this concept by comparing A1 with A2). While destroying controller instance angular internally emit's $destroy event over element & $scope of that element. So by having listener over $destroy event, we used to do stuff to ensure those object value/object/events should not available.
$scope.$on('$destroy', function(event){
//do stuff here
})
element.bind('$destroy', function(event){
//do stuff here
})
I am not sure if this is related to the subs-manager package I am using: https://github.com/kadirahq/subs-manager
But whenever I navigate between routes that do not load any data from the server, the rendered callback for the template does not get called.
This is a big issue because I have all the functions that are supposed to run when the template is rendered.
So Meteor removes the template from the DOM, and when it renders it back it does not call the rendered callback. Why? This is a huge issue for me.
We have a site with several AutoForms on different pages / routes. If a user triggers validation on a particular form and triggers some validation errors, and then leaves the page with that form, when they return to that page later on the data they have entered is gone, but any validation errors remain (fields are highlighted and validation error messages are shown).
How can we reset the form validation when a user leaves the form page?
I know we can use AutoForm.resetForm('our-form-id') to do the reset, and this works in the console, but I can't find the proper hook to hang it on. The onStop IronRouter hook for the page would seem to be the right place, but that triggers an error Can't call Tracker.flush while flushing. If I wrap it in a setTimeout with timeout 0, so it doesn't run until the next tick, it has no effect (presumably the template is destroyed by that point).
I would think when the template is destroyed the error state would be, too, but its not. Is there an undocumented way to "hard" reset errors even if an active template no longer exists?
We are using AutoForm 4.2.2.
You can reset the validations using
AutoForm.getValidationContext('form-id').resetValidation();
You need to use your router's exit hook to resetValidation, but you have to first get the context for your form. Here is how it is done in FlowRouter:
FlowRouter.route('/edit/:_id', {
name: 'editPage',
action: function() {
BlazeLayout.render('appLayout', {main: 'editPage'});
},
triggersExit: [function() {
AutoForm.getValidationContext('edit-form-id').resetValidation();
}]
});
For more information on flowRouter triggers see https://github.com/kadirahq/flow-router#triggers
I included a file (some-file.php) in my Ajax callback function. In that file I added some actions:
// some-file.php
add_action('load-post.php', 'function1');
add_action('load-post-new.php', 'function2');
But the functions (function1 and function2) never executed, however I'm positively sure that some-file.php is included.
add_action works perfectly if I called it inside my plugin file directly. I have problem with it when I'm calling it inside my Ajax callback.
Why this happens and how can I fix it?
I am retrieving a list of files from a web service and displaying them as links. When someone clicks on the link, the file should start downloading. The problem is that no direct access to the file exists. Here is the process to download a file:
User clicks on link
Server calls web service to retrieve file
Browser is loading for as long as it takes to bring the file back from the web service
Browser finally offers file to user for download
To counter the unfavorable user experience of having to wait for the web service before the download starts, I would like to display a "Loading..." feedback dialog when a link is clicked, and have the dialog go away when the file is ready.
I am using jQuery, and have been playing around with adding an iframe to the page to load the file, but the problem I am having is I don't know how to determine that the file is ready.
I am looking for tips, not only on the client side to give ample feedback, but perhaps also on the server side (using ASP.Net), just in case I can do something to streamline the process. Thank you.
Update: To clarify, this is for downloading a file to a user's machine. What I'm specifically looking for is a way to determine when the file is ready for download. So, when step #4 above takes place, I'd like to remove the "Loading..." message.
It sounds like you need to expose a new request URL on your server, whose only job is to reply whether the web-service-retrieval has completed (or if not, how far it has got).
Have AJAX poll that service every few seconds, and remove the "Loading..." message when it replied that the file is ready.
The client should send the session ID (maybe also a file ID), so that the server knows which file is being asked about. The server side will need to be able to contact the running web-service-retrieval process/thread to ask it how far it got. (If it can't find the thread then presumably it has finished.)
you can use the complete option for $.ajax function in jquery which should get called when the request completes
You can have jQuery to wait for the click of the link and when the link is clicked show the display loading message.
Example that shows how to 'Loading - Please wait' Message Display Script you can follow.
EDIT-
Basically you want a progress bar monitor, which I have never seen it done with just javascript, but with flash or ajax.
Here is a File Upload Demo that should help.
If you're linking to an ASHX that is grabbing the file and writing it back to a stream, you can modify the links click event to display a message.
$(function () {
$("a.someClass").click(function () {
$("div.message").fadeIn(); // show a loading message
return true; // make sure the link still gets followed
});
});
The loading message can just be a spinner or something while waiting for the ASHX to write the response back.
Edit: Since you're not directly linking to the ASHX:
$(function () {
var ashxCallback = function (data, textStatus) {
// data could be: xmlDoc, jsonObj, html, text, etc...
this; // the options for this ajax request
// textStatus can be one of: "timeout", "error", "notmodified", "success", "parsererror"
alert(textStatus);
};
$("a.someClass").click(function () {
$("div.message").fadeIn(); // show a loading message
$.get("some.ashx?id=1234", "", ashxCallback);
return false;
});
});
Using jQuery.get() and jQuery.post().
Edit #2: I just had another thought. What if the Loading... message was in an iframe that redirected to the file? So you would display the iframe with jQuery, it would have the default message of Loading... and a little spinner animation, then set the iframe's src/location to the ASHX that takes forever to load. You could then give it an onload handler from the iframe's parent page that would hide/remove it. Let me know if you need sample code.
If preparation for the file takes less than default timeout of AJAX request, you may start AJAX request, displaying "Loading..." message to user. AJAX call then checks for file's availability, and when it becomes available - returns with the message (success or not) and gives a link for the file. AJAX request can even do file download, but that's for your option.