Reputation: 3331
I'll explain what I have so far. I have two controllers
which are both using a movieService
I have created which fetches a list of movies. The controllers are like this:
app.controller('MovieCtrl', ['$scope', 'movieService', function($scope, movieService) {
$scope.movieService = movieService;
}]);
app.controller('NavCtrl', ['$scope', 'movieService', function($scope, movieService) {
$scope.movieService = movieService;
}]);
My Service looks like this:
app.service('movieService', ['$http', function($http) {
var movie = undefined;
var relatedMovies = undefined;
var searchTerm = undefined;
this.update = function(search) {
searchTerm = search;
fetch();
};
function fetch() {
$http.get(/* some http call that puts data into movie */);
$http.get(/* some http call that puts data into relatedMovies */);
};
}]);
And my related view code:
<input type="text" ng-model="searchTerm" ng-model-options="{debounce: 1500}" ng-change="movieService.update(searchTerm)">
<h1>{{ movieService.movie.Title }}</h1>
So on my view I have a search bar that when submitting the search term will use movieService.update(searchTerm)
, which is working fine because I can log the output from fetch()
to console and it will show me the movie data.
Inside the movie
variable there is a Title
variable, so right now, I am using {{ movieService.movie.Title }}
to try and display the title of the movie in the view. The problem is that the $scope.movieService
data is not updated in real time, so if I run a new search within the service
, the data in the view will not be updated unless I manually do it. When the data in movieService
is updated, the view should be too.
So here comes my question, how would I make sure that these $scope.movieService
variables in the controllers
are always up-to-date with the service
? Should I use $watch
or something like that? What is the best way to achieve this?
Update: Added CodePen http://codepen.io/anon/pen/JdMxaZ
Upvotes: 1
Views: 3288
Reputation: 6323
The problem is that your movie
variable is just a variable in a service. Nothing about being a variable in a service grants the variable special powers. In order to see that variable in your controller, you need to make it part of the service itself. The service is just an object, and that's what you add your update
function to. You need to make your movie
and relatedMovies
variables part of the service object.
Here's one way to solve this problem. The movieData
object is just one way to solve this problem. Either way, you need to be changing the value of an object field as opposed to the value of a local variable.
app.service('movieService', function($http) {
var movieData = {
movie: undefined,
relatedMovies: undefined
};
var searchTerm = undefined;
movieData.update = function(search) {
// searchTerm is fine because you're not trying to access it from the
// controller
searchTerm = search;
fetch();
};
this.movieData = movieData;
function fetch() {
$http.get(/* movieData.movie = http data */);
$http.get(/* movieData.relatedMovies = http data */);
};
});
app.controller('MovieCtrl', [function($scope, movieService) {
$scope.movieService = movieService.movieData;
});
app.controller('NavCtrl', function($scope, movieService) {
$scope.movieService = movieService.movieData;
});
You can also set a variable to the value of this
in the service function and change the value of movie
and relatedMovies
on that variable.
app.service('movieService', function($http) {
var movieService = this;
// modifying this modifies movieService and vice-versa
this.movie = undefined;
this.relatedMovies = undefined;
var searchTerm = undefined;
this.update = function(search) {
// searchTerm is fine because you're not trying to access it from the
// controller
searchTerm = search;
fetch();
};
function fetch() {
$http.get(/* movieService.movie = http data */);
$http.get(/* movieService.relatedMovies = http data */);
};
});
app.controller('MovieCtrl', [function($scope, movieService) {
$scope.movieService = movieService;
});
app.controller('NavCtrl', function($scope, movieService) {
$scope.movieService = movieService;
});
Upvotes: 2
Reputation: 192
I usually store data in $rootScope so if you put the search result in $rootScope it will refresh real-time.
another method is to call the broadcast $rootScope.$broadcast(name, args) which is not really practical
Upvotes: -1