decurgia
decurgia

Reputation: 111

AngularJS: Displaying alerts using $broadcast

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:

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

Answers (1)

Jonathan Rowny
Jonathan Rowny

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

Related Questions