GNSPS GNSPS - 2 months ago 6
AngularJS Question

Angular.js: directive object in scope is always undefined

EDIT: Forked @EliteOctagon's plunker and oddly it's working! Can't understand why the code below isn't. http://plnkr.co/edit/y8uvulA9RHQ1Y9mwzin1

EDIT2: Forked the previous plunker and added a $timeout to controller's logic and it stopped working! Guess it's really loading order. Check it out: http://plnkr.co/edit/ivmGQmEHTatNzBWhppyf

I'm new to angular and can't get my head wrapped around directive isolate scopes.

I need to create a directive to print out a

<span/>
in my page with info regarding and object in the view controller.

What I was trying to do is isolate the directive scope and pass the object through an attribute with two-way binding (see code below). However, when trying to access the object in the
link
function of the directive it always comes out as undefined.

What am I missing here?

Thank you in advance guys.

Directive use in html view template:

<party-starts party="party"></party-starts>


Directive JS code

.directive('partyStarts', function(){
return {
restrict: 'E',
template: '<div id="partyStart><i class="icon ion-pin"></i> </div>',
scope: {
party: '='
},
link: function(scope, el) {
var party = scope.party;
var icon = el.find('i');
var statusStr = angular.element('<span/>');
var final;

console.log('scope '+scope);

if(party.Diatodo){
if(party.datahora.isSame(moment(), 'day') || party.datahora.isSame(moment().add(1, 'd'), 'day')){
icon.css({
'color': 'green'
});
statusStr.text(' É hoje');
el.append(statusStr);
}else{
icon.css({
'color': '#999'
});
statusStr.text(' Começa em '+party.datahora.fromNow());
el.append(statusStr);
}
return;
}

if(party.datahora.unix() == party.datahoraf.unix()){
final = party.datahora.clone().add(1, 'd').hour(6);
}else{
final = party.datahoraf;
}

if(party.datahora.twix(final).isCurrent()){
icon.css({
'color': 'green'
});
statusStr.text(' Começou há '+party.datahora.fromNow());
el.append(statusStr);
}else if(party.datahora.twix(final).isFuture()){
icon.css({
'color': '#999'
});
statusStr.text(' Começa em '+party.datahora.fromNow());
el.append(statusStr);
}else{
icon.css({
'color': 'red'
});
statusStr.text(' Já terminou');
el.append(statusStr);
}
}
};
})

Answer

Wrap the directive's party scope variable in a watcher and wait for it to be initialized. In your case you don't do this and so all your logic is being run before scope.party is assigned.

link: function(scope, el) {

  var watcher = scope.$watch('party', function() {
    if(scope.party === undefined) return;

    // at this point it is defined, do work

    // delete watcher if appropriate
    watcher();
  })
}
Comments