מדריך 4: httpClient באנגולר - delete

מחבר:
בתאריך:

לגרסה האנגלית של המדריך Angular app with PHP backend: part 4 (DELETE)

מדריך זה הוא הרביעי בסדרה שמלמדת כיצד להשתמש ב-httpClient של Angular כדי לתקשר עם צד השרת של האפליקציה. במדריך זה, נמחק פריטי מידע באמצעות המתודה delete.

להורדת קוד האנגולר אותו נפתח במדריך

מדריכים נוספים בסדרה:

  1. Observable באנגולר - לא חובה אבל מומלץ מאוד
  2. הבאת נתונים מצד השרת באמצעות המתודה get
  3. יצירת רשומה חדשה באמצעות המתודה post
  4. עדכון רשומה קיימת באמצעות המתודה put
  5. מחיקת רשומה באמצעות המתודה delete
  6. ההקשר הרחב REST API

לחצו כדי לראות את הקוד בפעולה

 

1. ה-service האנגולרי

נוסיף ל-service את המתודה delete שקולטת את המידע מהקומפוננטה, ומשדרת אותו לצד השרת על גבי המתודה delete של httpClient.

src/app/car.service.ts

delete(id: any) {
    const params = new HttpParams()
      .set('id', id.toString());

    return this.http.delete(`${this.baseUrl}/delete`, { params: params });
}
  • המתודה שמשמשת לשידור המידע לצד השרת היא delete שמקבלת את נתיב ה-url בתור פרמטר ראשון ואת הפרמטר params אשר מכיל את ה-id של הפריט שמיועד למחיקה.
  • המידע שמוחזר מצד השרת כולל מידע ב-header על הצלחת או כישלון הפעולה.

הקוד המלא של ה-service:

src/app/car.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';

import { map } from 'rxjs/operators';
import { Car } from './car';

@Injectable({
  providedIn: 'root',
})
export class CarService {
  baseUrl = 'http ://localhost/api/';

  constructor(private http : HttpClient) {}

  getAll() {
    return this.http.get(`${this.baseUrl}list`).pipe(
      map((res: any) => {
        return res['data'];
      })
    );
  }

  store(car: Car) {
    return this.http.post(`${this.baseUrl}/store`, { data: car }).pipe(
      map((res: any) => {
        return res['data'];
      })
    );
  }

  update(car: Car) {
    return this.http.put(`${this.baseUrl}/update`, { data: car });
  }

  delete(id: any) {
    const params = new HttpParams()
      .set('id', id.toString());

    return this.http.delete(`${this.baseUrl}/delete`, { params: params });
  }
}

 

2. קוד הקלאס של הקומפוננטה

במדריך זה, נוסיף לקומפוננטה את המתודה deleteCar שקולטת את ה-id של הפריט שמעוניינים למחוק, ונרשמת למתודה delete שמספק ה-service.

src/app/app.component.ts

deleteCar(id: number) {
    this.resetAlerts();
    this.carService.delete(id).subscribe(
      (res) => {
        this.cars = this.cars.filter(function (item) {
          return item['id'] && +item['id'] !== +id;
        });

        this.success = 'Deleted successfully';
      },
      (err) => (this.error = err)
    );
}
  • השימוש ב- subscribe בגלל שהמתודה delete היא observable.
  • הצפי הוא לאחת משתי אפשרויות של מידע שיחזיר ה- observable. שגיאה או הצלחה.

הקוד המלא של הקומפוננטה הרי הוא לפניכם:

src/app/car.component.ts

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

import { Car } from './car';
import { CarService } from './car.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  cars: Car[] = [];
  car: Car = { model: '', price: 0 };

  error = '';
  success = '';

  constructor(private carService: CarService) {}

  ngOnInit() {
    this.getCars();
  }

  resetAlerts() {
    this.error = '';
    this.success = '';
  }

  getCars(): void {
    this.carService.getAll().subscribe(
      (data: Car[]) => {
        this.cars = data;
        this.success = 'Success in retrieving the list';
      },
      (err) => {
        this.error = err.message;
      }
    );
  }

  addCar(f: NgForm) {
    this.resetAlerts();

    this.carService.store(this.car).subscribe(
      (res: Car) => {
        // Update the list of cars
        this.cars.push(res);

        // Inform the user
        this.success = 'Created successfully';

        // Reset the form
        f.reset();
      },
      (err) => (this.error = err.message)
    );
  }

  updateCar(name: any, price: any, id: any) {
    this.resetAlerts();

    this.carService
      .update({ model: name.value, price: price.value, id: +id })
      .subscribe(
        (res) => {
          this.success = 'Updated successfully';
        },
        (err) => (this.error = err)
      );
  }

  deleteCar(id: number) {
    this.resetAlerts();
    this.carService.delete(id).subscribe(
      (res) => {
        this.cars = this.cars.filter(function (item) {
          return item['id'] && +item['id'] !== +id;
        });

        this.success = 'Deleted successfully';
      },
      (err) => (this.error = err)
    );
  }
}

 

3. ה-HTML של הטופס

זוכרים את הרשימה שמציגה את שם המכונית ומחירה ומאפשרת עריכה (אם אינכם בטוחים במה מדובר נא להתחיל מהמדריך הראשון בסדרה), את הרשימה הזו נשנה כדי לאפשר מחיקה של כל פריט בנפרד. לשם כך, נוסיף לטופס כפתור שלחיצה עליו שולחת את המידע על הפריט שיש למחוק לטיפול הקלאס של הקומפוננטה.

src/app/app.component.html

<div id="theList">
  <h2>The list</h2>

  <div class="list-group">
    <div *ngFor="let item of cars;let i = index;" class="list-group-item row">
      <div class="col-md-4">
        <input type="text"
               [(ngModel)]="cars[i].model"
               class="form-control"
               required
               pattern="^[a-zA-Z ]+$"
               #model="ngModel"
               [ngClass]="{ 'is-invalid': model.touched && model.invalid }">
      </div>
      <div class="col-md-4">
        <input type="number"
               [(ngModel)]="cars[i].price"
               class="form-control"
               required
               #price="ngModel"
               [ngClass]="{ 'is-invalid': price.touched && price.invalid }">
      </div>
      <div class="col-md-4">
        <input type="button"
               value="Update"
               class="btn btn-success btn-sm"
               [disabled]="model.invalid || price.invalid"
               (click)="updateCar(model, price, item.id)">
         
        <input type="button"
               value="Delete"
               class="btn btn-danger btn-sm"
               (click)="deleteCar(item.id? item.id:0)">

      </div>
    </div>
  </div>
</div>
  • כל פריט של הרשימה מודפס בשורה נפרדת.
  • לחיצה על הכפתור מעבירה את המידע אודות ה-id של הפריט לקומפוננטה להמשך טיפול באמצעות המתודה deleteCar.

 

להורדת קוד האנגולר אותו נפתח במדריך

4. צד השרת

זה קוד ה-PHP שמטפל במחיקת הפריטים בצד השרת:

<?php
require 'connect.php';

// Extract, validate and sanitize the id.
$id = ($_GET['id'] !== null && (int)$_GET['id'] > 0)? mysqli_real_escape_string($con, (int)$_GET['id']) : false;

if(!$id)
{
  return http_response_code(400);
}

// Delete.
$sql = "DELETE FROM `cars` WHERE `id` ='{$id}' LIMIT 1";

if(mysqli_query($con, $sql))
{
  http_response_code(204);
}
else
{
  return http_response_code(422);
}

במקרה של שגיאה מוחזר קוד ממשפחת ה-400.

הצלחה גורמת להחזרת קוד תגובה 204 , שמשמעותו שהפעולה הצליחה ושגוף התגובה (payload) ריק.

במדריך הבא נסביר את הארכיטקטורה של REST API שלפיה עקרונותיה נכתב צד השרת של האפליקציה.

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

הוסף תגובה חדשה

 

= 7 + 9

תמונת המגיב

חיה בתאריך: 31.03.2019

תודה

תמונת המגיב

אביגיל בתאריך: 21.01.2020

מהמם

תמונת המגיב

בנימין בתאריך: 20.01.2021

מה זה?
const params = new HttpParams()
.set('id', id.toString());

תמונת המגיב

יוסי בן הרוש בתאריך: 22.01.2021

מוסיף את ה-query param לכתובת שאיתה האפליקציה פונה לצד השרת.
בדוגמה, הפרמטר הוא id ונאמר שהערך שלו הוא 5:
https://yoursite.co.il/api/delete?id=5

תמונת המגיב

רותי בתאריך: 01.07.2021

האם הקוד האגולרי מתאים לעבודה גם אם צד שרת API CONTROLER?