-1

I am using UI Router and UI Bootstrap in my Angular app. I'd like to use a service so that I can display alert messages from various controllers. I want the alert to display at the top of the screen. Any suggestions on how to modify the code below so that the alert will display at the top of the page and display messages from different controllers?

I'm using this Stack Overflow post as a model.

HTML:

<alert ng-repeat="alert in allInfos()" type="{{alert.type}}" close="closeAlert($index)"
     ng-cloak>{{alert.msg}}</alert>

Service:

.factory('Informer', function(){

  var messages = [];
  var Informer = {};

  Informer.inform = function(msg, type) {
    messages.push({
    msg: msg,
    type: type
   });
  };

  Informer.allInfos = function() {
    return messages;
   };

  Informer.remove = function(info) {
    messages.splice(messages.indexOf(info), 1);
  };
  return Informer;
 })

Controller:

.controller('PaymentFormCtrl',
  function ($scope, $http, Informer) {

    $scope.handleStripe = function () {
     Informer.inform("There was a problem authorizing your card.", "danger");

      $scope.messages = 'problem';   
      $scope.allInfos = Informer.allInfos;
      $scope.remove = Informer.remove;

    }
  };
});

.controller('ContactFormCtrl',
  function ($scope, $http, Informer) {
 //. . . 
     Informer.inform("There is already an account with that email address", "danger");

      $scope.messages = 'problem';   
      $scope.allInfos = Informer.allInfos;
      $scope.remove = Informer.remove;

    }
  };
});

Routers:

.state('home', {
  url: '/',
   views: {
    'top': {
      templateUrl: 'views/bigHero.html'
      },
    'bottom': {
      templateUrl: 'views/home.html',
      controller: 'HomeCtrl'
    }
    }
   })

.state('payment', {
  url: '/payment',
   views: {
    'top': {
      templateUrl: 'views/customerinfo.html',
      controller: 'ContactFormCtrl'
     },
    'bottom': {
      templateUrl: 'views/creditcard.html',
      controller: 'PaymentFormCtrl'
      },
   }
  });
  });
Community
  • 1
  • 1
Ken
  • 3,091
  • 12
  • 42
  • 69

1 Answers1

0

You really have three good options that I can think of off the top of my head.

  1. Create a global or what i like to call a "RootController" of your application bound higher up in your DOM so that the other controllers scope naturally extends it. i.e.:

    <div ng-controller="RootController">
      <div ui-view></div>
    </div>
    
  2. You can create a parent state with UI Router that both your child states inherit, giving a similar effect to the case above:

    $stateProvider.state('parent', {controller: 'ParentController'});
    $stateProvider.state('parent.child1', {controller: 'Child1Controller'});
    $stateProvider.state('parent.child2', {controller: 'Child2Controller'});
    
  3. You can pass all shared functionality through a service, which acts as an error message to your necessary controllers.

    myService.service('errorService', function() {
      this.errorMessage = 'Everything is happy!';
    });
    myService.controller('PaymentFormCtrl', function($scope, errorService) {
      $scope.errorService = errorService;
      $scope.setError = function() {
        errorService.errorMessage = 'An error happened!';
      };
    }); 
    
tmanion
  • 401
  • 2
  • 11
  • Thank you. Option 3 is the most intuitive to me. But would that allow me to still have the alert always appear at the top of the page? – Ken May 03 '15 at 01:13
  • If you bind the error message to that scope you would be fine, which means injecting that service into that top of the page template. So yep! – tmanion May 04 '15 at 00:46