Как опубликовать выбранные флажки в виде массива из углового в API

Я создал компонент "form-page" в модуле "form":

форма-page.component.html:

<form [formGroup] = "form" (submit) = "onSubmit()">
    <div>
        <label for = "carmodel">Car Model:</label>
        <input type = "text" class = "form-control" formControlName = "carmodel">
        <div *ngIf = "form.controls['carmodel'].touched && form.controls['carmodel'].errors">
          <div *ngIf = "form.controls['carmodel'].hasError('required')" class = "error">Carmodel is required.</div>
          <div *ngIf = "form.controls['carmodel'].hasError('minlength')">Carmodel should be minimum 3 characters.</div>
        </div>
    </div>

    <div>
        <label for = "carnum">Car Number:</label>
        <input type = "text" class = "form-control" formControlName = "carnum">
        <div *ngIf = "form.controls['carnum'].touched && form.controls['carnum'].errors">
          <div *ngIf = "form.controls['carnum'].hasError('required')" class = "error">carnum is required.</div>
        </div>
      </div>



    <div>
        <label for = "contactNumber">Contact Number:</label>
        <input type = "text" class = "form-control" formControlName = "contactNumber">
        <div *ngIf = "form.controls['contactNumber'].touched && form.controls['contactNumber'].errors">
          <div *ngIf = "form.controls['contactNumber'].hasError('required')" class = "error">Contact number is required.</div>
        </div>
    </div>
  
    <div>
      <label>Type of Service:</label>
      <div>
        <label><input type = "radio" name = "option" value = "Waterwash" formControlName = "option"> Waterwash </label>
      </div>
      <div>
        <label><input type = "radio" name = "option" value = "Fullservice" formControlName = "option"> Fullservice </label>
      </div>
      <div *ngIf = "form.controls['option'].touched && form.controls['option'].invalid">
        <div class = "error">Please select an option</div>
      </div>
    </div>
    <div>
      <label>Addons:</label>
      <div>
        <label><input type = "checkbox" value = "10%off First service visit" formControlName = "checkbox"> 10%off First service visit</label>
      </div>
      <div>
        <label><input type = "checkbox" value = "10%off Waterwash" formControlName = "checkbox"> 10%off Waterwash</label>
      </div>
      <div>
        <label><input type = "checkbox" value = "Free AC Inspection" formControlName = "checkbox"> Free AC Inspection</label>
      </div>
      <div *ngIf = "form.controls['checkbox'].touched && form.controls['checkbox'].invalid">
        <div class = "error">Please select at least one Addon</div>
      </div>
    </div>
    <div>
      <label>State:</label>
      <select formControlName = "state" (change) = "onStateChange()">
        <option *ngFor = "let state of states" [value] = "state">{{state}}</option>
      </select>
      <div *ngIf = "form.controls['state'].touched && form.controls['state'].invalid">
        <div class = "error">Please select a state</div>
      </div>
    </div>
 
    <div>
        <label>City:</label>
        <select formControlName = "city">
            <option *ngFor = "let city of cities[form.controls['state'].value]" [value] = "city">{{city}}</option>
        </select>
        <div *ngIf = "form.controls['city'].touched && form.controls['city'].invalid">
            <div class = "error">Please select a city</div>
        </div>
    </div>

    <button type = "submit" class = "btn btn-primary">Submit</button>
    <button type = "button" (click) = "Reset()">Reset</button>
    <button (click) = "goBack()">back</button>


    

</form>

форма-page.component.ts:

import { Component } from '@angular/core';
import { Location } from '@angular/common';
//
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
//
import { CarServiceService } from 'src/app/services/car-service.service';


@Component({
  selector: 'app-form-page',
  templateUrl: './form-page.component.html',
  styleUrls: ['./form-page.component.css']
})
export class FormPageComponent {

  form: FormGroup;
  states: string[] = ['Tamilnadu', 'Kerala', 'Karnataka','Maharastra'];
  cities: {[key: string]: string[]} = {
    'Tamilnadu': ['Chennai', 'Coimbatore','Madurai'],
    'Kerala': ['Trivandrum','Kochi','Kollam'],
    'Karnataka': ['Bangalore', 'Mysore'],
    'Maharastra': ['Mumbai', 'Pune']
  };
  

  constructor(private fb: FormBuilder,private location : Location,private carServiceService :CarServiceService) {

    this.form = this.fb.group({
      carmodel :['', [Validators.required, Validators.minLength(3)]],
      carnum :['', [Validators.required]],
      contactNumber: ['', [Validators.required, Validators.pattern(/^\d{10}$/)]],
      option: ['', Validators.required],
      checkbox: ['', Validators.required],
      state: ['', Validators.required],
      city: ['', Validators.required]
    });
  }

  goBack():void{
    this.location.back();
  }

  

  onSubmit() {
    if (this.form.valid) {
      this.carServiceService.addCar(this.form.value).subscribe(response =>{
        console.info(response);
      });

    } else {
      // Form is invalid, display error messages
      this.form.markAllAsTouched();
    }
  }



  Reset(){
    this.form.reset();
  }

  onStateChange() {
    const state = this.form.controls['state'].value;
    this.form.controls['city'].setValue('');
    if (state) {
      this.form.controls['city'].enable();
    } else {
      this.form.controls['city'].disable();
    }
  }
  //
}

Создал сервис под названием "car-service" для POST:

car-service.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CarServiceService {

  constructor(private http: HttpClient) { }

  addCar(formData : any): Observable<any>{
    return this.http.post<any>('https://localhost:7095/api/Forms/submit-form',formData);
  }
}

Я пытаюсь опубликовать значения формы в API. Когда я нажимаю отправить, я получаю ошибку 400.

POST https://localhost:7095/api/Forms/submit-form 400

Ошибка:

ERROR HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: 'OK', url: 'https://localhost:7095/api/Forms/submit-form', ok: false, …}error: {type: 'https://tools.ietf.org/html/rfc7231#section-6.5.1', title: 'One or more validation errors occurred.', status: 400, traceId: '00-88c37085e17ce434f174cf65d020c28e-1bd09d34125cb2dc-00', errors: {…}}headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}message: "Http failure response for https://localhost:7095/api/Forms/submit-form: 400 OK"name: "HttpErrorResponse"ok: falsestatus: 400statusText: "OK"url: "https://localhost:7095/api/Forms/submit-form"[[Prototype]]: 

В веб-API asp.net-core:

FormData.cs:

namespace AngularApi.Model
{
    public class FormData
    {
        public string Carmodel { get; set; }
        public string Carnum { get; set; }
        public string ContactNumber { get; set; }
        public string Option { get; set; }
        public List<string> Checkbox { get; set; }
        public string State { get; set; }
        public string City { get; set; }
    }
}

и вот мой FormController в API:

private static List<FormData> formsDataList = new List<FormData>();

[HttpPost("submit-form")]
        public IActionResult SubmitForm([FromBody] FormData formData)
        {
            // process the form data
            string carmodel = formData.Carmodel;
            string carnum = formData.Carnum;
            string contactNumber = formData.ContactNumber;
            string option = formData.Option;
            List<string> checkbox = formData.Checkbox;

            string state = formData.State;
            string city = formData.City;



            // validate the form data
 //           if (string.IsNullOrWhiteSpace(carmodel) || string.IsNullOrWhiteSpace(carnum) || string.IsNullOrWhiteSpace(contactNumber) || string.IsNullOrWhiteSpace(option) || checkbox == null || checkbox.Count == 0 || string.IsNullOrWhiteSpace(state) || string.IsNullOrWhiteSpace(city))
  //          {
  //              return BadRequest(new { Message = " Enter the required fields." });
   //         }
            formsDataList.Add(formData);


            //            return Ok(new { Message = "Form submitted successfully." });
            return Ok(formData);

        }

Входные данные даже не попадают в API. Поэтому я подозреваю, что проблема связана с HTTPClient и с флажком. Думаю, проблема связана с флажком. Потому что, если я полностью удалю поле флажка как из HTML-формы, так и из API, он будет работать отлично, и я смогу отправлять значения в API.

Может кто-нибудь сказать мне, как это решить.

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если вы зарегистрируете значение формы, вы получите следующее:

carmodel: "kia"
​carnum: "123"
​checkbox: true
​city: "Chennai"
​contactNumber: "456"
​option: "Waterwash"
state: "Tamilnadu"

Думаю, вы тоже видите проблему. Boolean не является списком строк. Кроме того, вы дали для всех трех опций одно и то же имя элемента управления.

Вы можете ф. е. используйте массив строк или, что еще лучше, FormArray и сгенерируйте флажки с помощью ngFor.

Сначала я определил значения флажков:

checkboxes = [
    { value: '10%off First service visit', name: '10%off First service visit' },
    { value: '10%off Waterwash', name: '10%off Waterwash' },
    { value: 'Free AC Inspection', name: 'Free AC Inspection' },
  ];

Кстати, для меня немного необычно иметь значения в виде строки. Я имею в виду, что вы скорее будете хранить идентификаторы в базе данных. Но в любом случае.

Затем используйте FormArray в конструкторе форм.

checkbox: new FormArray([], Validators.required)

и создайте для него геттер

get checkboxesFormArray() {
    return this.form.controls['checkbox'] as FormArray;
  }

После этого заполните его

addCheckboxes() {
    this.checkboxes.forEach(() =>
      this.checkboxesFormArray.push(new FormControl(''))
    );
  }

И добавьте обработчик события для обработки проверенного события изменения.

checkedChanged(e) {
    let index = this.checkboxes.findIndex(
      (item) => item.value === e.target.value
    );
    if (e.target.checked) {
      this.checkboxesFormArray.controls[index].setValue(e.target.value);
    } else {
      this.checkboxesFormArray.controls[index].setValue('');
    }
  }

Это необходимо для установки прибл. управляющее значение для выбранной строки.

А вот так выглядит шаблон

  <div>
    <label>Addons:</label>
    <div *ngFor = "let cbx of checkboxesFormArray.controls; let i = index">
      <label formArrayName = "checkbox">
        <input type = "checkbox" [formControlName] = "i" (change) = "checkedChanged($event)" [value] = "checkboxes[i].value">
        {{checkboxes[i].name}}
      </label>
    </div>  
  </div>

И здесь вы можете найти работающую демо-версию stackblitz.

Если это то, что вы ищете, пожалуйста, отметьте это как ответ.

Эй, именно это то, с чем я имею дело. Я получаю логические значения вместо получения массива выбранных флажков. Я не уверен в использовании FormArray, новичок в этом, можете ли вы дать быструю демонстрацию с кодом, это было бы очень полезно

zack 02.04.2023 17:32

Я получаю одну ошибку, "ошибка TS7006: параметр "e" неявно имеет тип "любой". checkedChanged(e) {}".

zack 03.04.2023 04:46

Я изменил его на тип «любой» и исправил

zack 03.04.2023 05:05

Вместо <input type=checkbox> вы можете попробовать использовать <mat-selection-list>. всегда будет возвращать значение в логическом формате. он вернет массив выбранного значения. Код будет:

<mat-selection-list formControlName = "checkbox">
    <mat-list-option value = "10%off First service visit"> 10%off First service 
     visit</mat-list-option>
    <mat-list-option value = "10%off Waterwash" 10%off Waterwash</label></mat- 
    list-option>
    <mat-list-option value = "Free AC Inspection"> Free AC Inspection</mat- 
    list-option>
  </mat-selection-list>

Примечание. MatSelectionList является компонентом Angular Material. Сначала вы должны импортировать его в свой модуль.

Другие вопросы по теме