17. HttpModule

PostsComponent:

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

import { AppError, NotFoundError, BadRequestError } from '../common/app-error';
import { PostService } from '../services/post.service';

@Component({
  selector: 'app-posts',
  template: `
        <input #box (keyup.enter)="create(box)" type="text" class="form-control">
        <ul class="list-group">
              <li *ngFor="let post of posts" class="list-group-item">
                <input type="text" class="form-control" [value]="post.title">
              <button (click)="update(post)" class="btn btn-outline-info btn-sm">Update</button>
              <button (click)="delete(post)" class="btn btn-outline-danger btn-sm">Delete</button>
              </li>
        </ul>
  `
})
export class PostsComponent implements OnInit {

  posts: any[];

  constructor(private postService: PostService) { }

   create(input: HTMLInputElement) {
     const post = { title: input.value };
     this.posts.splice(0, 0, post);
     input.value = '';
     this.postService.create(post)
          .subscribe(newPost => {
            post['id'] = newPost.id;
            console.log(newPost);
          }, (error: AppError) => {
            this.posts.splice(0, 1);
            if (error instanceof BadRequestError) {
            alert('an expected error occured.');
            console.log(error);
          } else {
            throw error;
            }
          });
   }

   read() {
     this.postService.getAll().subscribe(posts => this.posts = posts);
   }

   update(post) {
     this.postService.update(post)
              .subscribe(updatedPost => {
                const index = this.posts.indexOf(post);
                this.posts.splice(index, 1, post);
                console.log(updatedPost);
              });
   }

   delete(post) {
     const index = this.posts.indexOf(post);
     this.posts.splice(index, 1);
     this.postService.delete(post.id)
            .subscribe(null,
            (error: AppError) => {
              this.posts.splice(index, 0, post);
              if (error instanceof NotFoundError) {
                alert('an expected error occured.');
                console.log(error);
              } else {
                throw error;
              }
            });
   }

   ngOnInit() {
     this.read();
   }

}

PostService:

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

import { DataService } from './data.service';

@Injectable()
export class PostService extends DataService {

  constructor(http: Http) {
    super('https://jsonplaceholder.typicode.com/posts', http);
   }

}

DataService:

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

import { AppError, NotFoundError, BadRequestError } from '../common/app-error';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';

@Injectable()
export class DataService {

  constructor(private apiURL: string, private http: Http) { }

  create(resource) {
    return this.http.post(this.apiURL, JSON.stringify(resource))
                    .map(response => response.json())
                    .catch(this.handleError);
  }

  getAll() {
    return this.http.get(this.apiURL)
                    .map(response => response.json())
                    .catch(this.handleError);
  }

  update(resource) {
    return this.http.patch(this.apiURL + '/' + resource.id, JSON.stringify({ title: resource.title }))
                    .map(response => response.json())
                    .catch(this.handleError);
  }

  delete(id) {
    return this.http.delete(this.apiURL + '/' + id)
                    .map(response => response.json())
                    .catch(this.handleError);
  }

  private handleError(error: Response) {
    if (error.status === 400) {
    return Observable.throw(new BadRequestError(error.json()));
    }
    if (error.status === 404) {
      return Observable.throw(new NotFoundError());
    }
    return Observable.throw(new AppError(error));
  }

}

AppError:

export class AppError {
    constructor(public originalError?: any) { }

}

export class NotFoundError extends AppError {

}

export class BadRequestError extends AppError {

}

AppErrorHandler:

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

export class AppErrorHandler implements ErrorHandler {

        handleError(error) {
          alert('an unexpected error occured.');
          console.log(error);
        }

}

TechnologiesComponent:

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

@Component({
  selector: 'app-technologies',
  template: `
        <div class="row">
          <div class="col-6">
          <h2>{{ title }}</h2>
          <app-posts></app-posts>
        </div>
        <div class="col">
            <img class="w-100 p-3 rounded-circle" [src]="imageUrl" />
            <app-my-love></app-my-love>
        </div>
      </div>
  `
})
export class TechnologiesComponent {
  title = 'List of Technologies';
  imageUrl = './assets/polymer3.jpg';

}

Let's view the results in our Chromium Web Browser:

GithubService:

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

import { DataService } from './data.service';

@Injectable()
export class GithubService extends DataService {

  constructor(http: Http) {
    super('https://api.github.com/users/NilsHolger/followers', http);
   }

}

GithubFollowersComponent:

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

import { GithubService } from '../services/github.service';

@Component({
  selector: 'app-github-followers',
  template: `
            <h2>My Followers</h2>
            <div class="media" *ngFor="let follower of followers">
              <img class="mr-3 round" [src]="follower.avatar_url" alt="Generic placeholder image">
                <div class="media-body">
                  <h5 class="mt-0 font-weight-bold">{{ follower.login}}</h5>
                  <a href="{{follower.html_url}}" target="_blank">{{ follower.html_url}}</a>
                </div>
            </div>
  `,
  styles: [`.round { width: 80px; height: 80px; border-radius: 100%; }`]
})
export class GithubFollowersComponent implements OnInit {
  followers: any[];

  constructor(private githubService: GithubService) { }

  ngOnInit() {
    this.githubService.getAll().subscribe(followers => {
      this.followers = followers;
      console.log(followers);
    });
  }

}

Let's view the running application in Chromium:

results matching ""

    No results matching ""