מדריך 2: httpClient באנגולר - post

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

לגרסתו האנגלית של המדריך Angular app with PHP backend: part 2 (POST).

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

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

1. ה-html של הטופס

את הטופס נוסיף מתחת לרשימה שפיתחנו ,במדריך הקודם, והוא כולל שני חלקים:

א. דיבים שמציגים את הודעות השגיאה וההצלחה, במידה והם קיימות:

src/app/app.component.html

<div class="alert alert-danger" *ngIf="error">{{error}}</div>
<div class="alert alert-success" *ngIf="success">{{success}}</div>

ב. הטופס עצמו:

src/app/app.component.html

<div id="theForm">
  <h2>The form</h2>
  <form #f="ngForm" name="theForm" (submit)="addCar(f)">
    <div class="form-group">
      <label>Model</label>
      <input type="text"
            class="form-control"
            name="model"
            [(ngModel)]="car.model"
            #carModel="ngModel"
            required
            pattern="^[a-zA-Z]+$">
      <span class="help-block danger" *ngIf="carModel.errors?.required && carModel.touched">
        The model name is required
      </span>
      <span class="help-block danger" *ngIf="carModel.errors?.pattern && carModel.touched">
        The model name can only contain the letters a-z or A-Z
      </span>
    </div>

    <div class="form-group">
      <label>Price</label>
      <input type="number"
            class="form-control"
            name="price"
            required
            [(ngModel)]="car.price"
            #carPrice="ngModel">
      <span class="help-block danger" *ngIf="carPrice.errors?.required && carPrice.touched">
        The price is required
      </span>
    </div>

    <button
        class="btn btn-primary btn-sm"
        [disabled]="f.invalid">Add</button>
  </form>
</div>

* הטופס הוא אנגולרי, ואם לא ברור איך הוא עובד אז אני ממליץ בחום לקרוא את המדריך על טפסים אנגולריים.

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

המידע מוזן לשדות, ונשלח עם המתודה addCar לטיפול הקוד של הקומפוננטה.

 

2. קוד הקומפוננטה

במדריך הקודם פיתחנו את המתודה getCars שמביאה את רשימת המכוניות. במדריך זה, נוסיף לקומפוננטה את המשתנים error ו-success, שיקלטו את הודעות השגיאה וההצלחה.

src/app/app.component.ts

error = '';
success = '';

נאתחל את הטופס באמצעות אתחול האובייקט car ששייך לקלאס Car.

car = new Car('', 0);

נוסיף לקוד הקומפוננטה את המתודה addCar שקולטת את הערכים שמוזנים לטופס, ושולחת את הערכים ל-service.

addCar(f) {
    this.resetAlerts();

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

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

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

במקרה של הצלחה, מופעלת המתודה reset, שמאתחלת את הטופס.

המתודה נרשמת למתודה store של ה-service , ושולחת לו את הערכים שהמשתמשים הזינו לטופס.

ההרשמה מתבצעת באמצעות subscribe בגלל שהמתודה store היא observable.

הצפי הוא לאחת משתי אפשרויות של מידע שיוחזר מה- observable:

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

 

3. ה-service

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

src/app/car.service.ts

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

המתודה שמשמשת לשידור המידע לצד השרת היא post שמקבלת את נתיב ה-url בתור פרמטר ראשון וגם את האובייקט car שמכיל את המידע שהתקבל מהקומפוננטה.

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

בשגיאות מטפלת הפונקציה handleError.

 

4. צד השרת

זה קוד ה-PHP שמטפל באחסון המידע בצד השרת:

store.php

<?php
require 'connect.php';

// Get the posted data.
$postdata = file_get_contents("php://input");

if(isset($postdata) && !empty($postdata))
{
  // Extract the data.
  $request = json_decode($postdata);
	

  // Validate.
  if(trim($request->data->model) === '' || (int)$request->data->price < 1)
  {
    return http_response_code(400);
  }
	
  // Sanitize.
  $model = mysqli_real_escape_string($con, trim($request->data->model));
  $price = mysqli_real_escape_string($con, (int)$request->data->price);
    

  // Store.
  $sql = "INSERT INTO `cars`(`id`,`model`,`price`) VALUES (null,'{$model}','{$price}')";

  if(mysqli_query($con,$sql))
  {
    http_response_code(201);
    $car = [
      'model' => $model,
      'price' => $price,
      'id'    => mysqli_insert_id($con)
    ];
    echo json_encode(['data'=>$car]);
  }
  else
  {
    http_response_code(422);
  }
}

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

במידה והמידע מאוחסן בהצלחה במסד הנתונים מוחזר קוד תגובה 201 וגם מערך אשר כולל את ה-id של הרשומה החדשה במסד הנתונים.

במדריך הבא נלמד כיצד לערוך את המידע.

 

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

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

 

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

 

= 5 + 6