AngularJS Services

Published on May 08, 2014

I wrote my first AngularJS service today. It was nothing big, I was just trying to keep from repeating code on every screen. On the site, an alert shows up after a user adds or updates a record. Angular-ui-bootstrap was giving me most of the functionality I wanted, but it doesn't have a way for the alerts to close automatically after a certain amount of time. I had already figured out how to get around that, but I was repeating the code in every controller. So I went ahead and wrote a service for it.

var alert = angular.module('myAlerts', []).service('alertService', function ($timeout) {
  var _alerts = [];

  this.setAlerts = function (alerts) {
    _alerts = alerts;
  };

  this.addAlert = function (alert) {
    _alerts.push(alert);
    return check();
  };

  var check = function () {
    if (_alerts.length > 1) {
      _alerts.splice(0, 1);
    }
    return _alerts;
  };

  this.timeDelete = function (alerts) {
    _alerts = alerts;
    var delay = 10000;
    $timeout(function () {
      removeAlert();
    }, delay);
    return _alerts;
  };

  var removeAlert = function () {
    _alerts.splice(0, 1);
  };
});

To learn how to do this, I referred to this blog post by Tyler McGinnis. It clearly and simply walks through the differences between factories, services, and providers in AngularJS. Before reading that, I didn't know what the difference was, so that was a good starting point.

I decided on using a service, mostly from a suggestion from a co-worker. It was pretty simple though to use, and made sense after reading Tyler's post. I put the service under its own angular.module so that several pages could easily reuse it.

var alert = angular.module('myAlerts', [])
  .service('alertService', function ($timeout)){

The next part could have been done several ways. For this site, we only wanted one alert at a time to show. So when you add an alert to the _alerts list, it then checks to see if there was already an alert in the list. If so, it removes the first one, leaving the most recent alert in the list by itself. The service then returns the _alerts list to the controller so that it can be displayed properly by the page.

this.addAlert = function (alert) {
  _alerts.push(alert);
  return check();
};

var check = function () {
  if (_alerts.length > 1) {
    _alerts.splice(0, 1);
  }
  return _alerts;
};

Finally, I added another function that the controller calls to delete the remaining alert in the list after 10 seconds. The function takes in the controller's alerts list and then removes the alert after 10 seconds using $timeout. This way the alert can be shown on the page and the controller knows about it.

this.timeDelete = function (alerts) {
  _alerts = alerts;
  var delay = 10000;
  $timeout(function () {
    removeAlert();
  }, delay);
  return _alerts;
};

Overall, this was a pretty simple service, but it allowed me to put minimal repeating code on each page, whereas before this I had all the alerts code on each page (6 pages before I switched it). If you still have questions on the differences of factories, services, and providers, go ahead and read the blog post I referred to earlier. Hopefully seeing this in practice may help as well.