How to run function in AngularJS controller on document ready?

How to run function in AngularJS controller on document ready?

I have a function within my angular controller, I’d like this function to be run on document ready but I noticed that angular runs it as the dom is created.
function myController($scope)
{
$scope.init = function()
{
// I’d like to run this on document ready
}

$scope.init(); // doesn’t work, loads my init before the page has completely loaded
}

Anyone know how I can go about this?

Solutions/Answers:

Solution 1:

We can use the angular.element(document).ready() method to attach callbacks for when the document is ready. We can simply attach the callback in the controller like so:

angular.module('MyApp', [])

.controller('MyCtrl', [function() {
    angular.element(document).ready(function () {
        document.getElementById('msg').innerHTML = 'Hello';
    });
}]);

http://jsfiddle.net/jgentes/stwyvq38/1/

Solution 2:

See this post How to execute angular controller function on page load?

For fast lookup:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

This way, You don’t have to wait till document is ready.

Related:  Append an array to another array in JavaScript [duplicate]

Solution 3:

Angular initializes automatically upon DOMContentLoaded event or when
the angular.js script is evaluated if at that time document.readyState
is set to ‘complete’. At this point Angular looks for the ng-app
directive which designates your application root.

https://docs.angularjs.org/guide/bootstrap

This means that the controller code will run after the DOM is ready.

Thus it’s just $scope.init().

Solution 4:

Angular has several timepoints to start executing functions. If you seek for something like jQuery’s

$(document).ready();

You may find this analog in angular to be very useful:

$scope.$watch('$viewContentLoaded', function(){
    //do something
});

This one is helpful when you want to manipulate the DOM elements. It will start executing only after all te elements are loaded.

UPD: What is said above works when you want to change css properties. However, sometimes it doesn’t work when you want to measure the element properties, such as width, height, etc. In this case you may want to try this:

$scope.$watch('$viewContentLoaded', 
    function() { 
        $timeout(function() {
            //do something
        },0);    
});

Solution 5:

I had a similar situation where I needed to execute a controller function after the view was loaded and also after a particular 3rd-party component within the view was loaded, initialized, and had placed a reference to itself on $scope. What ended up working for me was to setup a watch on this scope property and firing my function only after it was initialized.

// $scope.myGrid property will be created by the grid itself
// The grid will have a loadedRows property once initialized

$scope.$watch('myGrid', function(newValue, oldValue) {
    if (newValue && newValue.loadedRows && !oldValue) {
        initializeAllTheGridThings();
    }
});

The watcher is called a couple of times with undefined values. Then when the grid is created and has the expected property, the initialization function may be safely called. The first time the watcher is called with a non-undefined newValue, oldValue will still be undefined.

Related:  Change name of download in javascript

Solution 6:

Here’s my attempt inside of an outer controller using coffeescript. It works rather well. Please note that settings.screen.xs|sm|md|lg are static values defined in a non-uglified file I include with the app. The values are per the Bootstrap 3 official breakpoints for the eponymous media query sizes:

xs = settings.screen.xs // 480
sm = settings.screen.sm // 768
md = settings.screen.md // 992
lg = settings.screen.lg // 1200

doMediaQuery = () ->

    w = angular.element($window).width()

    $scope.xs = w < sm
    $scope.sm = w >= sm and w < md
    $scope.md = w >= md and w < lg
    $scope.lg = w >= lg
    $scope.media =  if $scope.xs 
                        "xs" 
                    else if $scope.sm
                        "sm"
                    else if $scope.md 
                        "md"
                    else 
                        "lg"

$document.ready () -> doMediaQuery()
angular.element($window).bind 'resize', () -> doMediaQuery()