I was making a little website with Angular the other day, and I wanted to have a search box in my nav bar that could be used from any page. When the search control is used, the user is sent to a search page that displays results but also lets users run additional searches. Both search functions use the same angular factory to execute their searches. Unfortunately, I was finding that the nav bar search control wouldn’t update search results when used from the search page.
I was able to solve the problem by using $broadcast and $on. It’s pretty simple, and it looks a lot cleaner than a lot of $watch solutions that I ran into while looking for a solution.
Here’s what my factory looks like:
app.factory('searchService', ['$rootScope', '$http', function ($rootScope, $http) {
var factory = {
search: search,
getResults: getResults
};
var _results = [];
function search(criteria) {
return $http.post(_serviceBase + 'api/search', criteria).then(function (results) {
_results = results.data;
$rootScope.$broadcast('searchCompleted', _results);
return results;
});
};
function getResults() {
return _results;
}
return factory;
}]);
And here’s my searchController that handles the broadcast event with $on:
app.controller('searchController', ['$scope', 'searchService', function ($scope, searchService) {
$scope.criteria = {};
$scope.results = searchService.getResults();
$scope.search = function () {
searchService.search($scope.criteria).then(function (results) {
$scope.results = results.data;
}, function (error) {
console.error(error.data.message);
});
};
$scope.$on('searchCompleted', function (results) {
$scope.results = searchService.getResults();
});
}]);
Note the use of $rootScope in the factory. Broadcasting the change is a single line of code, and handling the event in relevant controllers is pretty simple, too. Nice!