I want to use ng-infinite-scroll (https://sroze.github.io/ngInfiniteScroll/). But when I want to call function from my service (injected to controller) nothing happened (this function doesn't trigger). When I call function not from the service but from $scope of the controller - everything works fine. How to call function from the injected service in infinite-scroll directive?
My HTML structure:
<div class="col-xs-12 publications-container" ng-controller="showPublicationsCtrl">
<h3 class="publ-heading">Proposed Publications</h3>
<ul class="list-group" infinite-scroll="publicationsFactory.getPublications()" infinite-scroll-disabled='publicationsFactory.busyLoadingData'>
<li ng-repeat="publication in publications" class="list-unstyled list-group-item" ng-cloak>
<p class="text-warning">Author: <i>{{publication.author}}, {{publication.timestamp | date: 'MMM. d, y'}}</i></p>
<p ng-text-truncate="publication.text" ng-tt-words-threshold="3">{{publication.text}}</p>
<p class="text-muted">Channels: <i>{{publication.channels.join(", ")}}</i></p>
</li>
</ul>
</div>
My showPublicationsCtrl
controller:
twitterApiApp.controller("showPublicationsCtrl", ['publicationsFactory', '$scope', function (publicationsFactory, $scope) {
publicationsFactory.getPublications();
$scope.publications = publicationsFactory.publications;
}]);
My publicationsFactory
service:
angular.module('twitterApiApp').factory('publicationsFactory', ['$http', function($http) {
var publicationsFact = {};
publicationsFact.publications = [];
publicationsFact.busyLoadingData = false;
publicationsFact.getId = function() {
publicationsFact.id = publicationsFact.publications.length > 0 ?
publicationsFact.publications[publicationsFact.publications.length-1]['id'] : 0;
};
publicationsFact.getPublications = function () {
console.log("Triggered");
if (publicationsFact.busyLoadingData) return;
publicationsFact.busyLoadingData = true;
publicationsFact.getId();
$http.get("/Publications?id_gte=" + publicationsFact.id + "&_limit=2").then(function(response) {
for (var i = 0; i < response.data.length; i++) {
publicationsFact.publications.push(response.data[i]);
};
});
publicationsFact.busyLoadingData = false;
};
return publicationsFact;
}]);
If I create some function in my controller, for example $scope.myFunction
and then in HTML structute I assign infinite-scroll
attribute to myFunction()
the function will be successfully executed. So, I think maybe there are some mistakes in the way I inject the service in the controller. But everything else except ng-inginite-scroll works as planned.
infinite-scroll
is binded to $scope.publicationsFactory :
<ul class="list-group" infinite-scroll="publicationsFactory.getPublications()" infinite-scroll-disabled='publicationsFactory.busyLoadingData'>
but publicationsFactory
is not available in your scope, you must expose it like this :
twitterApiApp.controller("showPublicationsCtrl", ['publicationsFactory', '$scope', function (publicationsFactory, $scope) {
// Expose publication factory
$scope.publicationsFactory = publicationsFactory;
publicationsFactory.getPublications();
$scope.publications = publicationsFactory.publications;
}]);
How to update $scope.publications with latest publications retrieved using Factory
Your factory can return a promise resolved with the latest publications, change your code like this :
angular.module('twitterApiApp').factory('publicationsFactory', ['$http', '$q', function($http, $q) {
var publicationsFact = {};
publicationsFact.publications = [];
publicationsFact.busyLoadingData = false;
publicationsFact.getId = function() {
publicationsFact.id = publicationsFact.publications.length > 0 ?
publicationsFact.publications[publicationsFact.publications.length - 1]['id'] : 0;
};
/**
* Get latest publications
* @returns {object} A promise
*/
publicationsFact.getPublications = function() {
var deferred = $q.defer();
console.log("Triggered");
if (publicationsFact.busyLoadingData) return;
publicationsFact.busyLoadingData = true;
publicationsFact.getId();
$http.get("/Publications?id_gte=" + publicationsFact.id + "&_limit=2").then(function(response) {
for (var i = 0; i < response.data.length; i++) {
publicationsFact.publications.push(response.data[i]);
};
// Resolve promise with updates publications list
deferred.resolve(publicationsFact.publications);
}, function(error) {
// Reject promise with error message
deferred.reject(error.message);
});
publicationsFact.busyLoadingData = false;
// Return promise
return deferred.promise;
};
return publicationsFact;
}]);
Then, in your controller :
twitterApiApp.controller("showPublicationsCtrl", ['publicationsFactory', '$scope', function (publicationsFactory, $scope) {
// Expose publication factory
$scope.publicationsFactory = publicationsFactory;
publicationsFactory.getPublications()
.then(function(results) {
$scope.publications = results;
});
}]);