What is Services?
- Classes that can send functionality and data across multiple components.
- Keeps components lean
- DRY – Don’t repeat yourself
- Ideal place for Ajax calls using the HTTP requests module
Create a new file
/services/my-service.service.ts
- Import @Injectable and create class
- Add as a provider to @ngModule
- Call from components
Generating Services with Angular-CLI
ng g service services/my-service
Add the “module=app.module” flag to automatically add as a provider
ng g s services/data --module=app.module
services/data.service.ts
import { Injectable } from '@angular/core';
import { User } from '../models/User';
@Injectable()
export class DataService {
users: User[];
constructor() {
this.users = [
{
firstName: 'John',
lastName: 'Doe',
email: 'john@gmail.com',
isActive: true,
registered: new Date('01/02/2018 08:30:00'),
hide: true
},
{
firstName: 'Kevin',
lastName: 'Johnson',
email: 'kevin@yahoo.com',
isActive: false,
registered: new Date('03/11/2017 06:20:00'),
hide: true
},
{
firstName: 'Karen',
lastName: 'Williams',
email: 'karen@gmaial.com',
isActive: true,
registered: new Date('11/02/2016 10:30:00'),
hide: true
}
];
}
getUsers(): User[] {
console.log('Fetching users from service...');
return this.users;
}
addUser(user: User) {
this.users.unshift(user);
}
}
Component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { DataService } from '../../services/data.service';
import { User } from '../../models/User';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
user: User = {
firstName: '',
lastName: '',
email: ''
}
users: User[];
showExtended: boolean = true;
loaded: boolean = false;
enableAdd: boolean = false;
showUserForm: boolean = false;
@ViewChild('userForm') form: any;
constructor(private dataService: DataService) { }
ngOnInit() {
this.users = this.dataService.getUsers();
this.loaded = true;
}
onSubmit({value, valid}: {value: User, valid: boolean}) {
if(!valid){
console.log('Form is not valid');
} else {
value.isActive = true;
value.registered = new Date();
value.hide = true;
this.dataService.addUser(value);
this.form.reset();
}
}
}
HTML
<button (click)="showUserForm = !showUserForm" class="btn btn-dark mb-3">Add User</button>
<div class="card card-body mb-3" *ngIf="showUserForm">
<h2>Add User</h2>
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
<div class="form-group">
<label>First Name</label>
<input
type="text"
[(ngModel)]="user.firstName"
[ngClass]="{'is-invalid':userFirstName.errors && userFirstName.touched}"
class="form-control"
name="firstName"
#userFirstName="ngModel"
required
minlength="2"
>
<div [hidden]="!userFirstName.errors?.required" class="invalid-feedback">
First name required
</div>
<div [hidden]="!userFirstName.errors?.minlength" class="invalid-feedback">
Must be at least 2 characters
</div>
</div>
<div class="form-group">
<label>Last Name</label>
<input
type="text"
[(ngModel)]="user.lastName"
[ngClass]="{'is-invalid':userLastName.errors && userLastName.touched}"
class="form-control"
name="lastName"
#userLastName="ngModel"
required
minlength="2"
>
<div [hidden]="!userLastName.errors?.required" class="invalid-feedback">
Last name required
</div>
<div [hidden]="!userLastName.errors?.minlength" class="invalid-feedback">
Must be at least 2 characters
</div>
</div>
<div class="form-group">
<label>Email</label>
<input
type="email"
[(ngModel)]="user.email"
[ngClass]="{'is-invalid':userEmail.errors && userEmail.touched}"
class="form-control"
name="email"
#userEmail="ngModel"
required
pattern="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"
>
<div [hidden]="!userEmail.errors?.required" class="invalid-feedback">
Email name required
</div>
<div [hidden]="!userEmail.errors?.pattern" class="invalid-feedback">
Email is not valid
</div>
</div>
<button [disabled]="!userForm.form.valid" class="btn btn-block mb-3">Add New User</button>
</form>
</div>
<ul class="list-unstyled" *ngIf="loaded && users?.length > 0">
<li class="card card-body mb-2" *ngFor="let user of users" [class.bg-light]="user.isActive">
<h3>{{ user.firstName }} {{ user.lastName }}
<small>
<button (click)="user.hide = !user.hide" class="btn btn-dark btn-sm">
<i [ngClass]="user.hide ? 'fa fa-plus' : 'fa fa-minus'"></i>
</button>
</small>
</h3>
<ul class="list-group" *ngIf="!user.hide">
<li class="list-group-item">Emial: {{ user.email }}</li>
<li class="list-group-item">Joined: {{ user.registered | date }}</li>
</ul>
</li>
</ul>
<h4 *ngIf="users?.length == 0">No Users Found</h4>
<h4 *ngIf="!loaded">Loading Users...</h4>