Im kinda new into angularjs and I'm trying to create a small movie database. Its the first time im using a factory and I wanted to make sure this is the right way to do it and how to use this factory in another function as display below?
I want this factory to run only once, so I could use it in any controller I like. However I'm lost why I can't use $scope.allMovies in the example below. Thanks in advance!
var app = angular.module('myApp', []);
app.factory('moviesService', ['$http', function($http) {
var allMovies = [];
var getMovies = function() {
$http.get('js/data.json').success(function(data) {
angular.forEach(data, function(movies) {
allMovies.push(movies);
});
})
}
getMovies();
var getAllMovies = function(){
return allMovies;
}
return {
getAllMovies: getAllMovies
};
}]);
app.controller('listController', ['$scope', 'moviesService', function($scope,moviesService) {
$scope.genres = ['All', 'Crime', 'Drama', 'Action', 'Comedy'];
$scope.allMovies = moviesService.getAllMovies();
$scope.moviesByGenre = [];
$scope.selectedGenre = 'All';
$scope.getMoviesByGenre = function() {
// code to get movies by genre goes here
// cant access $scope.allMovies from here, returns as an empty array
};
}]);
My index.html looks like:
<div ng-controller="listController">
<div ng-repeat="movies in allMovies">{{movies.title}}</div>
</div>
This works, I have a list of the movies.title i get from the data.json.
However, when I try to console.log $scope.allMovies from inside of the function getMoviesByGenre I get an emtpy array.
getMovies has asynchronous function $http.get, so you need use callback like this,
var app = angular.module('myApp', []);
app.factory('moviesService', ['$http', function($http) {
var getMovies = function (callback) {
$http.get('js/data.json').success(function(data) {
var allMovies = [];
angular.forEach(data, function(movies) {
allMovies.push(movies);
});
callback(allMovies);
})
}
return {
getAllMovies: getMovies
};
}]);
app.controller('listController', ['$scope', 'moviesService', function($scope, moviesService) {
$scope.genres = ['All', 'Crime', 'Drama', 'Action', 'Comedy'];
$scope.moviesByGenre = [];
$scope.selectedGenre = 'All';
$scope.getMoviesByGenre = function () {
moviesService.getAllMovies(function (allMovies) {
console.log(allMovies);
});
};
}])
or use promises
I think you are miss using getMovies()
inside the factory. getMovies()
callback should return the ajax request result not pushing to other variable because of the asynchronous ajax call.
var getMovies = function() {
$http.get('js/data.json').success(function(data) {
return data;
});
}
return {
getAllMovies: getMovies
};
this is because the http request inside your service is executed asynchronously. To overcome this problem you can use a $watchCollection function which will be executed after you modify the all movies array inside moviesService:
app.controller('listController', ['$scope', 'moviesService', function($scope, moviesService) {
$scope.genres = ['All', 'Crime', 'Drama', 'Action', 'Comedy'];
$scope.allMovies = moviesService.getAllMovies();
$scope.moviesByGenre = [];
$scope.selectedGenre = 'All';
$scope.getMoviesByGenre = function() {
// code to get movies by genre goes here
// cant access $scope.allMovies from here, returns as an empty array
};
$scope.$watchCollection('movies', function (newValue) {
getMoviesByGenre();
});
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.