I'm using the GridLoadingEffects library by Codrops along with Angular JS to feed it list items with data from wordpress. Everything works in terms of Angular retrieving the data via $http request and storing the variables asynchronously. The data is processed and binded to HTML via ng-bind-html.
<body ng-app="myApp">
<div class="container" ng-controller="myController">
<ul class="grid effect-6" id="grid" ng-bind-html="bindHTML(html_code)"></ul>
</div>
</body>
After a slight delay as a result of retrieving the data, I can see that the HTML is in fact loaded into the DOM in the inspector. However, the problem is that the GridLoadingEffects effect immediately sees that there are no list items in the DOM, and therefore throws an undefined error.
I'm not an experienced web developer, so I can't precisely determine where the call is made to check for the DOM's li
elements and apply the effect, and this library has many dependencies including modernizr.js, masonry.js, imagesloaded.js, AnimOnScroll.js, and more. What confuses me further is that these files are loaded in different places in the HTML, some in the head and some at the end of the body. So in terms of the execution flow, I'm really lost as to how to solve this problem. I'm not sure but I think this function is what instantiates the effect.
<script>
window.onload = function() {
new AnimOnScroll( document.getElementById( 'grid' ), {
minDuration : 0.4,
maxDuration : 0.7,
viewportFactor : 0.2
} );
}
</script>
It is to be placed at the end of the body, as per the example html file provided by Codrops. I think that in order to rectify the issue, the function above has to run once Angular has fed the data to the ul
tag. Even though there's a window.onload
attached to it, it probably doesn't consider that there's more to load with angular.
Am I correct in my assumptions? I'm sure there's an easy fix to this. Can anyone help?
UPDATE: Here is how the $http request is initiated:
(function() {
'use strict'
angular.module('myApp', [])
.controller('myController', myController);
myController.$inject = ['$scope', '$sce','$http']
function myController ($scope, $sce, $http) {
$http({
method : "GET",
url : myURL
})
.then(function(response) {
$scope.myData = response.data;
var list = new Array
for (var i = 0; i < $scope.myData.length; i++) {
var string = '<li><figure class="blurfilter semitransparent"><img src=myURL><figcaption><h3>' + $scope.myData[i]['title']['rendered'] + '</h3></figcaption></figure></li>';
list.push(string)
}
$scope.html_code = list.join("")
$scope.bindHTML = function(html_code) {
return $sce.trustAsHtml(html_code)
};
});
};
})();
UPDATE 2:
My HTML now using ng-repeat to separate model and view:
<li ng-repeat="(key, val) in myData">
<h3>{{val.title.rendered}}</h3>
</li>
And my angular code (omitted the http requests):
(function() {
'use strict'
angular.module('myApp', [])
.controller('myController', myController);
myController.$inject = ['$scope', '$sce','$http']
function myController ($scope, $sce, $http) {
$scope.$watch('myData', function() {
// if the myData is loaded
if ($scope.myData.length > 0) {
new AnimOnScroll( document.getElementById( 'grid' ), {
minDuration : 0.4,
maxDuration : 0.7,
viewportFactor : 0.2
});
}
});
Now I get $scope.myData is undefined. $scope.myData
is defined in the .then
of my http request. Maybe it's helpful to mention that this error points to a line in the angular.min.js file, not to my app.js.