Home > Software design >  How to set Angular model field, which has another model as data type
How to set Angular model field, which has another model as data type

Time:08-12

There's a model called category and a model called booking. Booking has a field of type Category:

export interface Category {
  id: number;
  name: string;
}

export interface Booking {
  id: number;
  value: number;
  category: Category;
  date: Date;
}

The data for a booking will be set through input fields.

HTML:

  <form #addBookingForm="ngForm" (ngSubmit)="createBooking(addBookingForm)">
    <div >
      <label for="value">Value of booking:</label><br>
      <input type="text" ngModel name="value"  id="value">
    </div>
    <div >
      <div >
        <div >
          <label for="category" >Category</label>
        </div>
        <select type="text" ngModel name="category"  id="category">
          <option selected>select...</option>
          <option value="1">Gift</option>
          <option value="2">Income</option>
          <option value="3">Bill</option>
        </select>
      </div>
    </div>
    <div>
      <button type="submit" >Save</button>
    </div>
  </form>

TypeScript:

  public createBooking(addBookingForm: NgForm) {
    this.bookingService.addBooking(addBookingForm.value).subscribe(
      (response: Booking) => {
        console.log(response);
      },
      (error: HttpErrorResponse) => {
        alert(error.message);
      }
    )
  }

This results in the following HTTP-request payload:

{value: "45.0", category: "2"}
category: "2"
value: "45.0"

The error response is 500 internal server error, because the category field isn't set correctly with the input fields I've created. I'd appreciate any recommendations.

EDIT

I turned the option input into category objects and the payload changed accordingly, but the category object has no detailed definition:

{value: "45.0", category: "category"}
category: "category"
value: "45.0"

This JSON string works fine for testing the REST API, something like this for the HTML/TS file should work (maybe a HTTP request that sends a string in this format, but with dynamic values?):

{
  "value": "70.0",
  "category": {
    "id": 2
  },
  "date": "2022-08-04"
}

CodePudding user response:

I think you can solve this by passing your complet category as value of the options like this:

  <select type="text" ngModel name="category"  id="category">
    <option selected>select...</option>
    <option *ngFor="let o of categoryOptions" [value]="o">{{o.name}}</option>
  </select>


  categoryOptions = [
    { id: 1, name: 'Test1' },
    { id: 2, name: 'Test2' },
    { id: 3, name: 'Test3' },
  ];

You also not have to pass your exact form object, you can map the date before sending over http.

public createBooking(addBookingForm: NgForm) {
    this.bookingService.addBooking({
        value: addBookingForm.value.value,
        category: {
            id: addBookingForm.value.categoryId,
        },
        date: "2022-06-06"
    }).subscribe(...)
}

CodePudding user response:

As @Flo and @Rajat already mentioned, the options have to be category objects. This resulted in another issue though. The category name got set instead of the id.

enter image description here

The solution is to use ngValue instead of value and give it the category list item, while the iteration via *ngFor takes place:

<select type="text" ngModel name="category"  id="category">
      <option selected>select...</option>
      <option *ngFor="let category of categories" [ngValue]="category">{{category.name}}</option>
</select>
  • Related