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!