Showing AngularJS $timeout progress bar - angularjs

I have a alert message that I want to hide after a while. I use $timeout and it works well. However, I want to add a small horizontal count-down (aka progress) bar at the bottom of this alert box to let the user know that their time is running out.
AngularJS $timeout doesn't seem to have any way to determine how long it has been running. How should I update my progressbar in this case?
I use the $timeout like this
$timeout(function(){
$scope.m.hideAlertMessage = true;
}, 10000)

You should use $interval to run on every second and update the counter scope variable, and when it gets to 10 you can kill the interval and do whatever you wanted to do.
E.g.
$scope.counter = 0;
$interval(function() {
$scope.counter++;
if($scope.counter == 10) {
// Do whatever you wanted
}
}, 1000, 10);
The third argument of $interval is the # of times to run.
Note that by default this is run in an iteration of $scope.$apply() so the changes to $scope.counter will be immediately visible in your view.

Related

Autosave form fields for every 15 sec in AgularJS without using $watch

I want to save a form field values every 15 sec with out using $watch and also it should stop executing once it has been moved to a different form. In the form I will be having many fields so I think $ watch will be having performance issue and also am not sure how to call all fields at once for %watch. So I decided to use $interval but I want to stop this execution once I moved to different controller or different form. If user comes back again to this form again this interval function should start automatically. please would you suggest me best way to handle this.
Use $interval like you are planning to do but assign it to a variable
with $scope.on('$destroy', function() { }); callback you can destroy the interval when switching to a different controller.
var intervalPromise = $interval(function() { // your code }, 15000);
$scope.$on('$destroy',function(){
if(intervalPromise)
$interval.cancel(intervalPromise);
});

How to achieve Recursion in angularJS

if(url.toUpperCase().indexOf("SKILL") != -1) {
$timeout(function () {
$("#ABC").click();
}, 500)
}
I am using $timeout to click the skill button and load the grid on U-I . Above code is not loading the U-I, but if i increase the time from 500 to 2500 then code is working properly, but I don't want to increase the timeout. Is it possible to use recursion so my code would work without increasing timeout?
Set this condition inside document ready. Maybe javascript don't found the elements, because them must be loaded first.
$(document).ready(function(){
//here
});

Watch for dom element in AngularJS

I'm looking for a pure angularJS way to call a controller method once a particular dom element is rendered. I'm implementing the scenario of a back button tap, so I need to scroll to a particular element once it is rendered. I'm using http://mobileangularui.com/docs/#scrollable.
Update: how my controller looks like:
$scope.item_ready=function(){
return document.getElementById($scope.item_dom_id).length;
};
$scope.$watch('item_ready', function(new_value, old_value, scope){
//run once on page load, and angular.element() is empty as the element is not yet rendered
});
Thanks
One hack that you could do and I emphasize hack here but sometimes it's just what you need is watch the DOM for changes and execute a function when the DOM hasn't changed for 500ms which is accepted as a fair value to say that the DOM has loaded. A code for this would look like the following:
// HACK: run this when the dom hasn't changed for 500ms logic
var broadcast = function () {};
if (document.addEventListener) {
document.addEventListener("DOMSubtreeModified", function (e) {
//If less than 500 milliseconds have passed, the previous broadcast will be cleared.
clearTimeout(broadcast)
broadcast = $window.setTimeout(function () {
//This will only fire after 500 ms have passed with no changes
// run your code here
}, 10)
});
}
Read this post Calling a function when ng-repeat has finished
But don't look at the accepted answer, use the 3rd answer down by #Josep by using a filter to iterate through all your repeat items and call the function once the $last property returns true.
However instead of using $emit, run your function...This way you don't have to rely on $watch. Have used it and works like a charm...

Find duration of a REST call in Angular.js

I want to find out the time taken by a REST service to send back the promise object. If a REST service takes more than lets say x seconds, I need to show user a spinner and once the promise object is obtained the normal flow should proceed.
Any ideas?
Thanks
Recording the time of the request seems unnecessary.
Why not just always setup a timeout that will trigger the spinner after x seconds.
In the success callback of the promise you can just destroy the timeout object preventing it from triggering the spinner if it's before x seconds. Then remove the spinner if it exists.
var duration = 1000 * 1; //1 sec
var timeout = setTimeout(releaseTheSpinner, duration);
var releaseTheSpinner = function() {
//Make spinner
}
Something.update(data).
success(function {
clearTimeout(timeout);
//kill spinner
})
Using setTimeout should suffice. For example:
$scope.useHttp = function() {
$http.get('path/to/stuff')
.success(function(data) {
hideSpinner();
//do stuff with data
});
setTimeout(showSpinner,1000); //will show the spinner after a second (1000 milliseconds).
};
Have a look at the ngProgress directive or the angular loading bar directive, which place a progress at the top of the page. This creates a general, uniform method of displaying progress. Even if the service responds quickly (which is when you don't want to show a progress), the bar moves very quickly. This isn't a direct answer to your question, but a suggested alternative to added complexity around timing and showing a spinner.

Updating an Angular model from a mouse drag event

When I drag an element that I have drawn on a canvas, I would also like its live x and y coordinates to be shown outside of the canvas.
A quick description..
View:
//some HTML, including a canvas
{{xCoord}} </br>
{{yCoord}}
Directive: (onDrag() is called whenever the user clicks on and drags an object)
someCanvasObject.onDrag() {
$scope.xCoord = canvasObject.x;
$scope.yCoord = canvasObject.y;
$scope.$digest();
}
However, when I use $scope.$digest() to change the outputted coordinates, I get an "$apply is already in progress" error because $digest() is called in quick succession by the drag rapidly modifying the coordinates.
Is there an alternative way to use $digest() that will not conflict when used rapidly in the way described above?
(I've been told $$phase is bad practice.)
You could start by trying something like this:
var timeout;
someCanvasObject.onDrag() {
$scope.xCoord = canvasObject.x;
$scope.yCoord = canvasObject.y;
if (timeout) $timeout.cancel(timeout);
timeout = $timeout(function () {
$scope.$digest();
});
}
The idea is that, every time the drag event runs, you trigger the digest, but if onDrag is called 10 times during a single digest, only one subsequent digest is queued.
Someone probably will have a better way to accomplish this, but this might get you started.

Resources