Message appears in modal and Page at the same time

I created a "message center" in Angularjs that injects messages on the screen. The message always appears when an error occurs in rest operations or success. This is done by an interceptor that checks if the response has a message header, if it is it injects the message and type into the provider, and the directive prints on the screen.

The problem is that the message appears in the Modal, which is right, and also appears on the page that called The modal the first time I open the page the other times does not appear.

First time I saved a user: insert the description of the image here

Second time, after closing the modal and the message that appeared on the listing screen: insert the description of the image here

Interceptor (which is configured not $httpProvider):

angular.module('app').factory('notificationInterceptor', function ($q, AlertService) {
    return {
        responseError: function(response) {
            addMessage(response);
            return $q.reject(response);
        },
        response: function(response) {
            addMessage(response);
            return response;
        }
    };

    function addMessage(response){
         var alert = response.headers('X-applicationMessage');
         if (angular.isString(alert)) {
            var mensagens = response.data.mensagens ;
            var timeout = 10000; 
            if(mensagens!= undefined){
                        mensagens.forEach(function(element, index, array) {
                            AlertService.add(element.messageType, element.body);
                    });
            }
         }
    }

Provider

'use strict'

angular.module('app').provider('AlertService',
        function() {
            this.$get = [ function() {
                var alerts = [];

                var exports = {
                    add : add,
                    clear : clear,
                    get : get
                }

                function clear() {
                    alerts = [];
                }

                function get() {
                    return alerts;
                }

                function add(type, msg) {
                    var alert = {
                        type : type,
                        msg : msg,
                    };

                    alerts.push(alert);

                    return alert;
                }

                return exports;
            } ];
        });

Directive

'use strict';
angular
        .module('app')
        .directive(
                'mcAlert',
                function(AlertService) {
                    return {
                        restrict : 'E',
                           template:  '<uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</uib-alert>',
                        controller : [ '$scope', function($scope) {
                            $scope.alerts = AlertService.get();

                            $scope.$on('$destroy', function() {
                                AlertService.clear();
                            });

                            $scope.closeAlert = function(index)  {
                                $scope.alerts.splice(index, 1);
                            }
                        }]
                    }
                });
Author: LINQ, 2016-03-04

1 answers

I think the best way to solve your problem without starting to mix scopes is to put in your AlertService who is the callback it should notify when AlertService receives notifications.

One way to do this would be to keep a list of callbacks in AlertService and delete them in destroy, another would be to keep an id per callback and try to access them by that Id.

Trying to exemplify the idea.

'use strict'

angular.module('app').provider('AlertService',
        function() {
            this.$get = [ function() {
                var alerts = [];
                var callbacks = [];
                var exports = {
                    add : add,
                    clear : clear,
                    get : get
                }

                function clear() {
                    alerts = [];
                    unregisterLastCallback();
                }
                function unregisterLastCallback(){
                   callbacks.remove(<lasts>);
                }
                function registerCallback(callback){
                   callbacks.push(callback);
                }

                //function get() {

                  //  return alerts;
                //}

                function add(type, msg) {
                    var alert = {
                        type : type,
                        msg : msg,
                    };

                    alerts.push(alert);
                    notify();
                    return alert;
                }

                function notify(){
                    callbacks.<PegueUltimoDaLista>(alerts)//passar cópia de alerts;

                 }

                return exports;
            } ];
        });

There in the directive would be thus

'use strict';
angular
        .module('app')
        .directive(
                'mcAlert',
                function(AlertService) {
                    return {
                        restrict : 'E',
                           template:  '<uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</uib-alert>',
                        controller : [ '$scope', function($scope) {

                            var updateCallback() = function(alerts){
                                $scope.alerts = alerts// certificar de que é uma cópia.
                            }                                      


                            AlertService.registerCallback( updateCallback);
                            $scope.$on('$destroy', function() {
                                AlertService.clear();
                            });

                            $scope.closeAlert = function(index)  {
                                $scope.alerts.splice(index, 1);
                            }
                        }]
                    }
                });

I think the implementation using a callback stack is maybe very confusing and easy to get wrong...but the idea I wanted to pass on is that you're going to have to have some way of identifying in AlertService or Controller which directive you're referring to so that only it gets notified when the alerts arrive.

 1
Author: Vinicius Zaramella, 2016-03-04 13:44:01