Reputation: 4428
I've created a directive with the following definition
LastMeet.directive("progressBar", function() {
return {
restrict: "A",
scope: {
meeting: "&meeting"
},
link: function(scope, elm, attrs) {
var meeting = scope.meeting();
// Gather the details we need about this meeting
var startDate = scope.meeting().start_datetime;
var deadline = scope.meeting().deadline;
var complete = scope.meeting().percentage_complete;
console.log(meeting);
console.log(meeting["start_datetime"]);
// No point doing anything if we're already at 100%
if (complete < 100.0) {
// Calculate how much to increment by every second
var diff = deadline - startDate;
var increment = diff / 60.0;
var timer;
scope.percentage = complete;
scope.onTimeout = function() {
if (scope.percentage < 100.0) {
scope.percentage += increment;
elm.css({ right: 100 - percentage + "%" });
timer = $timeout(scope.onTimeout, 1000);
}
}
// Setup our timer and get going :)
timer = $timeout(scope.onTimeout, 1000);
}
}
}
})
The meeting attribute is an object with a number of different properties. As you can see, I've added 2 console outputs, one for the meeting itself, and one for one of the properties I'm trying to access. My console has the following output
b {$resolved: false, $then: function, $get: function, $save: function, $query: function…}
$resolved: true
$then: function (callback, errback) {
agenda_items: Array[2]
deadline: 1365897600
description: "Meeting to discuss the progress of LastMeet"
faye_token: "7468585e529849ca992efbd3b9de6337"
icon: null
id: 20
name: "LastMeet"
percentage_complete: 100
start_datetime: 1365897600
__proto__: b
This is the output of the meeting object, which clearly shows the start_datetime
property contained. The second console output however is simply
undefined
Why is it that the meeting object is there, and I can see everything, but when I try and access the contained properties, I just get undefined every time?
Upvotes: 1
Views: 3346
Reputation: 4428
SUCCESS! So it appears to be an issue with the variable not being fully ready when the directive runs. The meeting object that it was looking at is created via a resource
which creates a placeholder object whilst it gets the server data, and then populates the object.
My guess, is angular saw that the object existed (actually the placeholder) but the values I wanted weren't actually there yet. Not sure why the console output showed them as being there but oh well. To fix it, I added a watch
statement to the object which is removed when it actually changes and gets populated. My directive now looks like this
LastMeet.directive("progressBar", function($timeout) {
return {
restrict: "A",
scope: {
meeting: "=meeting"
},
link: function(scope, elm, attrs) {
unwatch = scope.$watch('meeting', function(meeting) {
if (meeting) {
// Gather the details we need about this meeting
var startDate = meeting.start_datetime;
var deadline = meeting.deadline;
var complete = meeting.percentage_complete;
// No point doing anything if we're already at 100%
if (complete < 100.0) {
// Calculate how much to increment by every second
var diff = deadline - startDate;
var increment = diff / 60.0;
var timer;
scope.percentage = complete;
scope.onTimeout = function() {
if (scope.percentage < 100.0) {
scope.percentage += increment;
elm.css({ right: 100 - scope.percentage + "%" });
timer = $timeout(scope.onTimeout, 1000);
}
}
// Setup our timer and get going :)
timer = $timeout(scope.onTimeout, 1000);
}
unwatch();
}
}, true)
}
}
})
Now I have a few calculation issues but it's working :)
Upvotes: 2