Quick Look @ Angular Part III - Create a Service
Brett M. Nelson - Wednesday, February 22, 2017
So far we have used the Angular-CLI to create a simple app and add a component but before we add a second component lets create a service. This will allow us to share information between our current component, TaskListComponent
, and our future component tentatively named NewTaskComponent
. This way when we get around to making our new component we can have one point of access to how we manipulate our collection of tasks.
Add a Service
Create TaskService
ng g service ./services/task
You may have noticed that we added
./services/
to the path for our new service. I choose to do this so all services can be located in one folder. If I was making a service dedicated to one component I think I would create the service in the folder of the component.
This will create 2 files in a new folder at src/app/service/
:
task.service.ts
import { Injectable } from '@angular/core';
@Injectable() export class TaskService {
constructor() { }
}
task.service.spec.ts
/* tslint:disable:no-unused-variable */
import { TestBed, async, inject } from '@angular/core/testing'; import { TaskService } from './task.service';
describe('TaskService', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [TaskService] }); });
it('should ...', inject([TaskService], (service: TaskService) => { expect(service).toBeTruthy(); })); });
Share Data
As riveting as those are lets make the TaskListComponent
use the TaskService
to manage the state of the tasks list.
Lets move our tasks
array and the work we are doing for initializing it from the TaskListComponent
to the TaskService
.
Now our TaskService
should look like this:
Updated task.service.ts
import { Injectable } from '@angular/core'; import { Task } from '../models/task'; // <= This is new
@Injectable() export class TaskService {
tasks: Task[]; // <= This is new
constructor() { }
// New Method init() { this.tasks = [ { "title": "First Item", "complete": true, "description": "first task to do" } ]; }
}
This means we need a reference to the TaskService
in the TaskListComponent
now so we will add an import
for it and pass it in the constructor. We will also call the TaskService
init
method from the ngOnInit
so everything is initialized when we get things started.
Updated task-list.component.ts
import { Component, OnInit } from '@angular/core';
// import { Task } from '../models/task'; // <= Remove this
import { TaskService } from '../services/task.service'; // <= This is new
@Component({ selector: 'app-task-list', templateUrl: './task-list.component.html', styleUrls: ['./task-list.component.css'] }) export class TaskListComponent implements OnInit {
// tasks: Task[]; // <= Remove this
constructor(private _taskService: TaskService) { } // <= This Changed
ngOnInit() { // this.tasks = [ // <= Remove this // { // <= Remove this // "title": "First Item", // <= Remove this // "complete": true, // <= Remove this // "description": "first task to do" // <= Remove this // } // <= Remove this // ]; // <= Remove this
this._taskService.init() // <= This is new
}
}
Of course our template should be updated to use _taskService.tasks
instead of the now nonexistent tasks
on the controller.
Updated task-list.component.html
Now if you are watching your page reload with ng serve
you may notice it's not working. Opening the console will reveal a whole lot of error messages. This is because we didn't tell the app to use TaskService
and it doesn't know where to find it.
Register Service
To let Angular know we have a service we want to use we will have to register it as a provider at some level.
I say "at some level" because depending on the size of your app you may not want to register everything to be accesses from everywhere but we can talk about that later perhaps.
For now lets go to our app/app.module.ts
and add an import for the TaskService
and then pass it into the providers array.
Updated app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { TaskListComponent } from './task-list/task-list.component'; import { TaskService } from './services/task.service'; // <= This is new
@NgModule({ declarations: [ AppComponent, TaskListComponent ], imports: [ BrowserModule, FormsModule, HttpModule, AppRoutingModule ], providers: [ TaskService // <= This is new ], bootstrap: [AppComponent] }) export class AppModule { }
Now your app should load like before so we know things are working with our service.
Code
Code can be found at Github/BrettMN/quick-look
More Interesting?
Yay! We now have a service! Oddly our app looks exactly the same as it did without the service. Maybe this was a but more work than we will need for a simple TODO app, what do you think? Let me know by leaving a comment below or emailing brett@wipdeveloper.com.