timothym timothym - 21 days ago 12
AngularJS Question

$onInit does not immediately have bindings data

I have this component in my app:

<actions-bar actions="$ctrl.actionsBarData"></actions-bar>


Here is the controller / component definition:

.component('actionsBar', {
controller: 'actionsBarController',
bindings: {
actions: '<'
}
})

.controller('actionsBarController', function() {

var vm = this;

vm.$onInit = function() {
console.log(vm.actions);
setTimeout(function() {
console.log(vm.actions);
}, 500);
};
});


Take note of the two
console.log
statements within
$onInit
. In the browser the first logging statement prints
undefined
. The second statement, wrapped in
setTimeout
correctly prints out the
this.actions
object.

According to the Angular docs:


$onInit() - Called on each controller after all the controllers on an
element have been constructed and had their bindings initialized


If the bindings have been initialized, why is the data not immediately available? Why must I set a delay of 500ms before it is available?

If
$onInit
isn't the solution here, how can I reliably access the bindings data within my controller? It appears that this is correct lifecycle hook to use, and none of the other hooks appear to be what I want in this case.

Answer

This is because while the bindings have been initialized in the controller, they haven't necessarily been initialized where they are coming from. If you are populating your binding with an async call, the object is going to be undefined or empty.

$onChanges allows you to inspect changes that happen to your bindings.

vm.$onChanges = function (changesObj) {
    console.log(changesObj.actions);
}

If what I described above is happening, this will fix it for you.

EDIT: a word

Comments