Cory Rylan

My name is , Google Developer Expert, Speaker, Software Developer. Building Design Systems and Web Components.

Follow @coryrylan
Angular

Converting Angular 1 Services to the latest Angular Services

Cory Rylan

- 3 minutes

Updated

This article has been updated to the latest version Angular 17 and tested with Angular 16. The content is likely still applicable for all Angular 2 + versions.

With Angular 1 the Factory Service was one of the most popular ways to organize logic in your Angular 1 app. With Angular 2.x and later we migrate to using ES6/ES2015 classes over the factory/module pattern. In this post we will look at a simple Angular 1 factory service and convert it to an Angular 2.x+ service using ES2015 and TypeScript. We will also dig into how you can write your Angular 1 services in a way that will make your code easier to migrate to Angular in the future.

Factories

Factories are one of the most popular choices when it comes to structuring your Angular 1 services. We will convert our factory to use a Angular 1 .service which maps better to Angular 2.x+. The Angular 1 .service service takes a constructor function instead of an object like the .factory. Angular 1 will call the new keyword on our constructor function which will create a new instance of our service. Using ES2016 classes we will have a nice syntax to create our constructor function. So lets take a look at a simple data service that has some data shared between components and a couple of methods.

(function() {
  'use strict';

  angular.module('app').factory('dataService', dataService);

  function dataService() {
    var service = {
      data: data,
      loadData: loadData
    };

    var data = {
      items: []
    };

    return service;

    function loadData() {
      // Commonly where Http calls are made
      data.items = ['one', 'two', 'three'];
    }
  }
})();

So here we have an Angular 1.x factory. We can share data between components and controllers via our public data property. We also have a simple load function to load data. Now this is an overly simple service but want to focus on how this is converted to Angular 2.x+.

Angular 1.x Services

So now that we have our Angular 1.x Factory lets convert this to a Service and use an ES6/ES2015 JavaScript Class.

(function() {
  'use strict';

  class DataService {
    constructor() {
      this.data = {
        items: []
      };
    }

    loadData() {
      this.data.items = ['one', 'two', 'three'];
    }
  }

  angular.module('app').service('DataService', DataService);
})();

Now in this example you can see it's quite a bit different but functionally would work the same in your Angular 1 app. Notice instead of using .factory we call .service on our Angular module. This is slightly different because Angular will call the new keyword on our service and keep a single instance to use in the lifetime of our app. We could introduce ES6/ES2015 modules here but for simplicity sake we will see how those are used in Angular first.

Angular 2.x and later Services

So now that we see the difference between .service and .factory in Angular 1 lets take a look at how Angular 2.x+ services work. The latest Angular is written in TypeScript and looks to be the dominant language used for Angular apps. There are a lot of great benefits to TypeScript. TypeScript adds static typing to our ES6/ES2015 code. This is really great for large apps or teams.

So lets take a look at our Angular 2.x+ version of this same service.

export class DataService {
  data: { items: string[] };

  constructor() {
    this.data = {
      items: []
    };
  }

  loadData() {
    this.data.items = ['one', 'two', 'three'];
  }
}

// data.service.ts file

Looking at this code we see there are no references to Angular at all. This is because we are using ES2015 modules to export this class to be consumed by another. Notice the export keyword in front of our class. We will import this class in another file to register it to Angular. The syntax would look something like this: import { DataService } from 'data.service'; The rest of our code looks very similar to our Angular 1 Service.

Notice the second line: data: { items: any[] };; This line is TypeScript specific code. This is a type annotation for the TypeScript compiler. This tells TypeScript this property here will be an object with a items property that has an array of strings. This allows the IDE to have a better understanding of how the code works. We get better auto completion and the compiler can tell us if someone accidentally assigns the wrong data type to our list.

The great part about Angular services is that they are simple classes. No strange Angularisims to have to learn. I kept this post extremely simple to just focus on the constructs that are changing between Angular 1 and Angular2. To learn more about TypeScript take a look at Brice Wilson's great TypeScript In-depth course on PluralSight. To get a quick start to Angular check out John Pappa's fantastic intro course Angular 2: First Look and the angular.dev quick start.

Twitter Facebook LinkedIn Email
 

No spam. Short occasional updates on Web Development articles, videos, and new courses in your inbox.

Related Posts

Angular

Creating Dynamic Tables in Angular

Learn how to easily create HTML tables in Angular from dynamic data sources.

Read Article
Web Components

Reusable Component Patterns - Default Slots

Learn about how to use default slots in Web Components for a more flexible API design.

Read Article
Web Components

Reusable Component Anti-Patterns - Semantic Obfuscation

Learn about UI Component API design and one of the common anti-patterns, Semantic Obfuscation.

Read Article