Reputation: 111
I'm trying to display alert messages (success, warning, danger) on the index.html page:
...
</header>
<div ng-controller="AlertController">
<alert ng-repeat="alert in alerts" type="alert.status" close="closeAlert($index)">{{ alert.message }}</alert>
</div>
<div ng-view></div>
...
To do so I've written an AlertController in controllers.js. It might be a good idea to receive the alerts through $broadcast / $on.
Controllers.controller('AlertController', ['$scope', '$rootScope',
function ($scope, $rootScope) {
$scope.alerts = [];
$rootScope.$on('alert:success', function(message) {
$scope.alerts.push({'status': 'success', 'message': message});
});
$rootScope.$on('alert:warning', function(message) {
$scope.alerts.push({'status': 'warning', 'message': message});
});
$rootScope.$on('alert:danger', function(message) {
$scope.alerts.push({'status': 'danger', 'message': message});
});
$scope.closeAlert = function (alert) {
return this.closeAlertIndex($scope.alerts.indexOf(alert));
};
$scope.closeAlertIndex = function (index) {
return $scope.alerts.splice(index, 1);
};
}]);
But when I do use other Controllers the alerts do not get displayed:
Controllers.controller('LocationController', ['$scope', '$rootScope', '$routeParams', 'LocationService',
function ($scope, $rootScope, $routeParams, LocationService) {
$scope.Location = {};
$scope.Locations = [];
$scope.queryLocation = function () {
LocationService.query({active: $routeParams.active}, function (locations) {
$scope.Locations = locations;
$rootScope.$broadcast('alert:success', "Location queried: active = " + $routeParams.active);
console.log("Location queried");
}, function (error) {
$rootScope.$broadcast('alert:warning', "Unable to query location: " + error.message);
console.log("Unable to query location");
});
};
$scope.getLocation = function () {
LocationService.get({id: $routeParams.id}, function (location) {
$scope.Location = location;
$rootScope.$broadcast('alert:success', "Location got: " + location.id);
console.log("Location got");
}, function (error) {
$rootScope.$broadcast('alert:warning', "Unable to get location: " + error.message);
console.log("Unable to get location");
});
};
}]);
I can see the console.log() messages, but not the alerts. In the logs I do also see a 404 error on alert.html. Do I have to create an alert.html file to use the tag?
I did read some other posts where they suggested to use a service instead of a controller, but this didn't work on my page. Also I think it's a simple solution to just broadcast the alert...
How can I fix this?
Cheers
Thanks to the responses I did rewrite the code. I had to do the following to get it working:
The alert-tag did not work so I changed from ui-bootstrap.min.js to ui-bootstrap-tpls.min.js
New PubSubService based on glepretre's proposal
New AlertController:
Controllers.controller('AlertController', ['$scope', 'PubSubService', function ($scope, PubSubService) { $scope.alerts = [];
$scope.addAlert = function(status, message) {
$scope.alerts.push({'status': status, 'message': message});
};
$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
};
PubSubService.subscribe('alert', $scope.addAlert);}]);
Now I can add alerts using
PubSubService.publish('alert', 'warning', 'Unable to get location: ' + error.message);
But this solution is not using $broadcast.
Upvotes: 2
Views: 2919
Reputation: 7588
$broadcasts only go DOWN scopes and $emits go UP scopes. Use $emit combined with $rootScope. Since $rootScope is the top scope, all $emits will hit it. Additionally, I'd put that in a service instead of a controller, but I don't really know what you're doing.
Upvotes: 4