10. Services

Service:

import { Injectable } from '@angular/core';

@Injectable()
export class ArticleService {
  private title = 'To give anything less than your best is to sacrifice the gift.';

  getTitle() {
    return this.title;
  }

}

Component:

import { Component } from '@angular/core';
import { ArticleService } from '../article.service';

@Component({
  selector: 'app-article',
  template: `
      <h2>Article Component</h2>
      <button class="btn btn-danger" (click)="loadArticle()">Show Article</button>
      <h3>{{ title }}</h3>
  `
})
export class ArticleComponent {
        title = '';

        constructor(private articleService: ArticleService) { }

        loadArticle() {
          this.title = this.articleService.getTitle();
        }

}

Article Feature Module:

import { NgModule } from '@angular/core';
import { ArticleComponent } from './article.component';
import { ArticleService } from './article.service';


@NgModule({
  declarations: [ ArticleComponent ],
  providers: [ ArticleService ],
  bootstrap: [ ArticleComponent ],
  exports: [ ArticleComponent ]
})
export class ArticleModule { }

AppModule:

import { ArticleModule } from './article/article.module';

  imports: [
    BrowserModule,
    HttpModule,
    ReactiveFormsModule,
    FormsModule,
    RouterModule.forRoot(appRoutes),
    ArticleModule
  ]

Inject Service directly into Component:

import { Component } from '@angular/core';
import { ArticleService } from './article.service';

@Component({
  selector: 'app-article',
  template: `
      <p>Article Component</p>
      <button class="btn btn-danger" (click)="loadArticle()">Show Article</button>
      <h3>{{ title }}</h3>
  `,
  providers: [ ArticleService ]
})
export class ArticleComponent {
  title = '';

  constructor(private articleService: ArticleService) { }

  loadArticle() {
    this.title = this.articleService.getTitle();
  }

}

Polymorphic service utilisation:

export interface IArticleSource {
  getArticle(): IArticle;
}

export interface IArticle {
  title: string;
  body: string;
  notes?: string;
}

import { Injectable } from '@angular/core';

@Injectable()
export class ArticleService implements IArticleSource {
    private title = 'Angular 4 Love Affair';
    private body = 'Dedicated to the smartest and most beautiful woman in the world, Laura.';

    getArticle(): IArticle {
      return {
        title: this.title,
        body: this.body
      }
    }

}

@Injectable()
export class EditorArticleService extends ArticleService implements IArticleSource {
    private notes = 'Code with passion.';

    constructor() {
      super();
    }

    getArticle(): IArticle {
      return Object.assign({}, super.getArticle(), {
        notes: this.notes
      });
    }

}

Components:

import { Component } from '@angular/core';
import { ArticleService, EditorArticleService } from './article.service';

@Component({
  selector: 'app-default-view',
  template: `
          <h3>Default view</h3>
          <ng-content></ng-content>
  `,
  providers: [ ArticleService ]
})
export class DefaultViewComponent { }

@Component({
  selector: 'app-editor-view',
  template: `
          <h3>Editor view</h3>
          <ng-content></ng-content>
  `,
  providers: [ { provide: ArticleService, useClass: EditorArticleService } ]
})
export class EditorViewComponent { }

AppComponent:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
      <div class="row">
      <h1>{{ title }}</h1>
        <div class="col-md-6">
          <h2>Services</h2>
          <app-default-view>
              <app-article></app-article>
          </app-default-view>
          <app-editor-view>
              <app-article></app-article>
          </app-editor-view>
        </div>
        <div class="col-md-6">
            <app-princess></app-princess>
        </div>
      </div>
  `,
  styles: [``]
})
export class AppComponent {
  title = 'Angular 4 Love Affair';

}

Directive providers:

import { Directive } from '@angular/core';
import { ArticleService, EditorArticleService } from './article.service';

@Directive({
  selector: '[editor-view]',
  providers: [{ provide: ArticleService, useExisting: EditorArticleService }]
})
export class EditorViewDirective { }

AppComponent with directive:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
      <div class="row">
      <h1>{{ title }}</h1>
        <div class="col-md-6">
          <h2>Services</h2>
              <app-article editor-view></app-article>
              <app-article editor-view></app-article>
        </div>
        <div class="col-md-6">
            <app-princess></app-princess>
        </div>
      </div>
  `,
  styles: [``]
})
export class AppComponent {
  title = 'Angular 4 Love Affair';

}

Opaque tokens and useValue:

import { OpaqueToken } from '@angular/core';

export const IMAGE_URL = new OpaqueToken('image.url');

ArticleModule:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ArticleComponent } from './article.component';
import { EditorViewDirective } from './editor-view.directive';
import { DefaultViewComponent, EditorViewComponent } from './default-view.component';
import { ArticleService, EditorArticleService } from './article.service';
import { IMAGE_URL } from './image-url.token';

@NgModule({
  declarations: [ ArticleComponent,  EditorViewDirective, DefaultViewComponent, EditorViewComponent ],
  imports: [ CommonModule ],
  bootstrap: [ ArticleComponent ],
  providers: [ ArticleService, EditorArticleService, { provide: IMAGE_URL, useValue: 'http://vignette2.wikia.nocookie.net/disney/images/1/16/Princess-Ariel-disney-princess-39040276-900-900.jpg'} ],
  exports: [ ArticleComponent, EditorViewDirective, DefaultViewComponent, EditorViewComponent ]
})
export class ArticleModule { }

Component:

import { Component, Inject } from '@angular/core';
import { IMAGE_URL } from './image-url.token';

@Component({
  selector: 'app-article',
  template: `
          <img src="{{ imageUrl }}">
          <h2>My Polymer Princess</h2>
          <p>Author: Nils-Holger Nägele</p>
  `
})
export class ArticleComponent {
  imageUrl = '';

  constructor(@Inject(IMAGE_URL)private _imageUrl) {
    this.imageUrl = _imageUrl;
  }

}

results matching ""

    No results matching ""