Due to this scenario:
$scope.graph = {};
you can set defaults as follows
$scope.graph = {
height: 0,
width: 0
};
The values for height and width remain undefined until the watch is triggered. Your current implementation of watches does not account for checking if the values are undefined. The initial trigger of the watch is undefined, and it may not trigger again until the screen is resized.
$scope.$watch(function(){
return $window.innerWidth;
}, function(value) {
if(value){
console.log(value);
}
});
$scope.$watch(function(){
return $window.innerHeight;
}, function(value) {
if(value){
console.log(value);
}
});
Additionally, a $digest cycle is not automatically triggered on window resize, only during user events. Therefore, you'll need to implement the following:
$window.addEventListener('resize', debounce(function(){
$scope.$apply();
}, 500));
It's important to debounce the event to prevent it from being called too frequently, which could crash your application. A simple debounce function similar to David Walsh's debounce function is used here, but other libraries like lodash or jQuery may have built-in alternatives.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
Furthermore, binding the values in the manner seen above will not be updated by the $watches. To address this, use the following:
<h3>transform: translate({{ graph.width }}, {{ graph.height }});</h3>
An updated plunker link is provided for reference. Resize the right window to trigger the $watch function.
If you prefer to utilize $watchGroup, you can pass an array of functions instead of just a single function like so:
$scope.$watchGroup([function(){
return $window.innerWidth;
}, function(){
return $window.innerHeight;
}], function() {
$scope.graph.width = $window.innerWidth / 2;
$scope.graph.height = $window.innerHeight / 2;
});
A corresponding demonstration using this plunker is also available.