본문 바로가기

프론트엔드/앵귤러

앵귤러 라이브러리 - 앵귤러 HTTP클라이언트

반응형

 

앵귤러의 http모듈은 서버에 정보를 요청할 때 사용됩니다.


목차


사용방법

모듈사용을 위해 해당 모듈을 추가합니다.

// app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CommentComponent } from './components/comment/comment.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent, CommentComponent],
  imports: [BrowserModule, AppRoutingModule, HttpClientModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

필수는 아니지만 사용을 편의를 위해 서비스 파일과 모델파일을 추가합니다(아래 명령어를 통해 생성가능).

ng g s services/comment
ng g i models/comment

※ 모델을 생성하는 이유는 타입제약이 강한 앵귤러의 특성상 서버에서 요청한 데이터를 다른 변수에 지정할 때 일일이 지정해야 하는 수고를 덜어 주기 때문입니다.

타입 미설정
타입 설정

컴포넌트 하나에서 하는 것보다 각 기능을 담당하는 컴포넌트를 만들어서 하는 게 조금 더 실질적일 것 같아서 컴포넌트를 만들겠습니다. 아래 명령어를 사용하여 컴포넌트를 추기하고

ng g c components/comment
ng g c components/comment/comment-add
ng g c components/comment/comment-edit

경로를 지정합니다

// app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CommentAddComponent } from './components/comment/comment-add/comment-add.component';
import { CommentEditComponent } from './components/comment/comment-edit/comment-edit.component';
import { CommentComponent } from './components/comment/comment.component';

const routes: Routes = [
  { path: 'comment-add', component: CommentAddComponent },
  { path: 'comment-edit/:id', component: CommentEditComponent },
  { path: '', component: CommentComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

※ 요청할 서버

JSONPlaceholder - Free Fake REST API (typicode.com)

 

JSONPlaceholder - Free Fake REST API

{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. As of Oct 2022, serving ~1.7 billion requests each month.

jsonplaceholder.typicode.com


활용하기

1. GET

데이터를 불러오는 메서드로 서버에 대한 요청을 비동기 식으로 이루어지기 때문에 Observable을 활용하는 것이 편리합니다.

// comment.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Comment } from '../models/comment';

@Injectable({
  providedIn: 'root'
})
export class CommentService {
  URL = 'https://jsonplaceholder.typicode.com/comments/'    
    
  constructor(private http:HttpClient) { }

  getComments():Observable<Comment[]> {
    return this.http.get<Comment[]>(this.URL)
  }
}
// comment.component.ts

import { Component, OnInit } from '@angular/core';
import { Comment } from 'src/app/models/comment';
import { CommentService } from 'src/app/services/comment.service';

@Component({
  selector: 'app-comment',
  templateUrl: './comment.component.html',
  styleUrls: ['./comment.component.css'],
})
export class CommentComponent implements OnInit {
  comments: Comment[] = [];

  constructor(private commentService: CommentService) {}

  ngOnInit(): void {
    this.commentService.getComments().subscribe((comments) => {
      this.comments = comments;
    });
  }
}

<!-- comment.component.html -->

<div class="container">
  <div class="card" style="display: flex; flex-direction: column; justify-content: space-around; height: 150px; width: 600px; font-family: Arial, Helvetica, sans-serif; padding: 10px; background-color: antiquewhite; margin: 10px auto;" *ngFor="let i of comments">
    <p>{{i.id}}</p>
    <p>{{i.body}}</p>
    <div>
      <p>{{i.name}}</p>
      <p>{{i.email}}</p>
    </div>
  </div>
</div>

2. POST

데이터를 추가하는 메서드입니다.

// comment.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Comment } from '../models/comment';

@Injectable({
  providedIn: 'root',
})
export class CommentService {
  URL = 'https://jsonplaceholder.typicode.com/comments/';
  
  constructor(private http: HttpClient) {}

  getComments(): Observable<Comment[]> {
    return this.http.get<Comment[]>(this.URL);
  }

  addComment(body: string, name: string, email: string) {
    const comment: Comment = {
      body: body,
      email: email,
      name: name,
    };
    this.http.post(this.URL, comment).subscribe(result => {
      console.log(result)
    });
  }
}
// Comment-add.component.ts

import { Component, OnInit } from '@angular/core';
import { CommentService } from 'src/app/services/comment.service';

@Component({
  selector: 'app-comment-add',
  templateUrl: './comment-add.component.html',
  styleUrls: ['./comment-add.component.css'],
})
export class CommentAddComponent implements OnInit {
  constructor(private commentService: CommentService) {}

  ngOnInit(): void {}

  onSubmit(name: string, email: string, body: string) {
    this.commentService.addComment(body, email, name);
  }
}
<!-- comment-add.component.html -->

<form (submit)="onSubmit(name.value, email.value, body.value)" style="padding: 20px;">
  <input #name style="width: 100%; font-size: 1.4rem;" type="text" placeholder="name">
  <input #email style="width: 100%; font-size: 1.4rem;" type="text" placeholder="email">  
  <textarea  #body style="width: 100%; font-size: 1.4rem;" placeholder="content"></textarea>
  <button>Submit</button>
</form>

3. DELETE


목록을 보여주는 컴포넌트로 가서 삭제 버튼을 추가합니다

<!-- comment.component.html -->

<a routerLink="/comment-add">Add</a>
<div class="container">
  <div class="card"
    style="display: flex; flex-direction: column; justify-content: space-around; height: 150px; width: 600px; font-family: Arial, Helvetica, sans-serif; padding: 10px; background-color: antiquewhite; margin: 10px auto;"
    *ngFor="let i of comments">
    <p>{{i.id}}</p>
    <p>{{i.body}}</p>
    <div>
      <p>{{i.name}}</p>
      <p>{{i.email}}</p>
    </div>
    <button (click)="onDelete(i.id)">Delete</button>    
  </div>
</div>


// comment.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Comment } from '../models/comment';

@Injectable({
  providedIn: 'root',
})
export class CommentService {
  URL = 'https://jsonplaceholder.typicode.com/comments/';
  
  constructor(private http: HttpClient) {}

  getComments(): Observable<Comment[]> {
    return this.http.get<Comment[]>(this.URL);
  }

  addComment(body: string, name: string, email: string) {
    const comment: Comment = {
      body: body,
      email: email,
      name: name,
    };
    this.http.post(this.URL, comment).subscribe(result => {
      console.log(result)
    });
  }

  deleteComment(id:string) {
    this.http.delete(this.URL + id).subscribe(result => {
      console.log(result)
    })
  }
}
// comment.component.ts

import { Component, OnInit } from '@angular/core';
import { Comment } from 'src/app/models/comment';
import { CommentService } from 'src/app/services/comment.service';

@Component({
  selector: 'app-comment',
  templateUrl: './comment.component.html',
  styleUrls: ['./comment.component.css'],
})
export class CommentComponent implements OnInit {
  comments: Comment[] = [];

  constructor(private commentService: CommentService) {}

  ngOnInit(): void {
    this.commentService.getComments().subscribe((comments) => {
      this.comments = comments;
    });    
  }

  onDelete(id: string | undefined) {
    this.commentService.deleteComment(id as string);
  }
}
<!-- comment.component.html -->

<a routerLink="/comment-add">Add</a>
<div class="container">
  <div class="card"
    style="display: flex; flex-direction: column; justify-content: space-around; height: 150px; width: 600px; font-family: Arial, Helvetica, sans-serif; padding: 10px; background-color: antiquewhite; margin: 10px auto;"
    *ngFor="let i of comments">
    <p>{{i.id}}</p>
    <p>{{i.body}}</p>
    <div>
      <p>{{i.name}}</p>
      <p>{{i.email}}</p>
    </div>
    <button (click)="onDelete(i.id)">Delete</button>
    <button>Edit</button>
  </div>
</div>

4. PUT

데이터를 업데이트하는 메서드로 업데이트에 PUT과 FETCH를 사용가능합니다. 둘의 차이는 수정이 필요한 부분만 업데이트하는 FETCH와 달리 PUT은 모든 값을 새로운 값으로 대체한다는 점입니다.


목록을 보여주는 컴포넌트로 가서 편집버튼을 추가합니다. 이때 해당 아이템의 아이디를 경로에 포함해서 이동합니다.

<!-- comment.component.html -->

<a routerLink="/comment-add">Add</a>
<div class="container">
  <div class="card"
    style="display: flex; flex-direction: column; justify-content: space-around; height: 150px; width: 600px; font-family: Arial, Helvetica, sans-serif; padding: 10px; background-color: antiquewhite; margin: 10px auto;"
    *ngFor="let i of comments">
    <p>{{i.id}}</p>
    <p>{{i.body}}</p>
    <div>
      <p>{{i.name}}</p>
      <p>{{i.email}}</p>
    </div>
    <button (click)="onDelete(i.id)">Delete</button>
    <button>
      <a [routerLink]="['/comment-edit', i.id]">
        Edit
      </a>
    </button>
  </div>
</div>


PUT 메서드와 더불어 개별 아이템을 가져오는 GET메서드도 추가합니다(편집 페이지에서 기존 데이터를 보여주기 위해 사용).

// comment.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Comment } from '../models/comment';

@Injectable({
  providedIn: 'root',
})
export class CommentService {
  URL = 'https://jsonplaceholder.typicode.com/comments/';
  
  constructor(private http: HttpClient) {}

  getComments(): Observable<Comment[]> {
    return this.http.get<Comment[]>(this.URL);
  }

  addComment(body: string, name: string, email: string) {
    const comment: Comment = {
      body: body,
      email: email,
      name: name,
    };
    this.http.post(this.URL, comment).subscribe(result => {
      console.log(result)
    });
  }

  deleteComment(id:string) {
    this.http.delete(this.URL + id).subscribe(result => {
      console.log(result)
    })
  }

  getComment(id:string):Observable<Comment> {
    return this.http.get<Comment>(this.URL + id)
  }

  editComment(id:string, body: string, name: string, email: string) {
    const comment: Comment = {
      body: body,
      email: email,
      name: name,
    };

    this.http.put(this.URL + id, comment).subscribe(result => {
      console.log(result)
    })
  }
}

Edit 컴포넌트 클래스에서 ActivatedRoute 모듈을 활용하여 전송된 아이디를 수집하고 이를 활용하여 개별 아이템을 가져와

// component-edit.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Comment } from 'src/app/models/comment';
import { CommentService } from 'src/app/services/comment.service';

@Component({
  selector: 'app-comment-edit',
  templateUrl: './comment-edit.component.html',
  styleUrls: ['./comment-edit.component.css'],
})
export class CommentEditComponent implements OnInit {
  id!: string;
  comment!: Comment;
  constructor(
    private commentService: CommentService,
    private activatedRoute: ActivatedRoute
  ) {}

  ngOnInit(): void {
    this.id = this.activatedRoute.snapshot.params['id'];
    this.commentService.getComment(this.id).subscribe((comment) => {
      this.comment = {
        name: comment.name,
        body: comment.body,
        email: comment.email,
      };
    });
  }

  onSubmit(name: string, email: string, body: string) {
    this.commentService.editComment(this.id, body, email, name);
  }
}

템플릿과 연결하면

<!-- comment-add.component.html -->

<form (submit)="onSubmit(name.value, email.value, body.value)" style="padding: 20px;">
  <input #name style="width: 100%; font-size: 1.4rem;" type="text" placeholder="name" [value]="comment.name">
  <input #email style="width: 100%; font-size: 1.4rem;" type="text" placeholder="email" [value]="comment.email">  
  <textarea  #body style="width: 100%; font-size: 1.4rem;" placeholder="content" [value]="comment.body"></textarea>
  <button>Submit</button>
</form>

아래와 같이 기존 아이템 정보가 표시됩니다.

마지막으로 정보를 입력하고 전송하면 아래와 같이 업데이트가 된 것을 확인가능합니다 (개발자 도구 네트워크 탭)

이상으로 앵귤러 http를 활용해 보았습니다. 


폼 업데이트하기 (템플릿 폼)

 

앵귤러 폼 - Template-driven form

앵귤러 template-driven form을 설정하는 방법을 보겠습니다. 먼저, 폼을 사용하기 위해서는 앵귤러 폼 라이브러리에서 forms 모듈을 가져와야 합니다. //scr/app/app.module.ts import { NgModule } from '@angular/core';

jin-co.tistory.com

 

소스코드

https://github.com/jin-co/web-mobile/tree/master/Angular/cheat-sheet/http

 

GitHub - jin-co/web-mobile

Contribute to jin-co/web-mobile development by creating an account on GitHub.

github.com


참고

Traversy Media - YouTube

 

Traversy Media

Traversy Media features the best online web development and programming tutorials for all of the latest web technologies from the building blocks of HTML, CSS & JavaScript to frontend frameworks like React and Vue to backend technologies like Node.js, Pyth

www.youtube.com

 

728x90
반응형