Как использовать и экспортировать массив объектов внутри моего класса в Angular

#angular #spring-boot

#angular #spring-boot

Вопрос:

Я настраиваю приложение с Spring boot и Angular для изучения интерфейса. У меня есть несколько REST API, предоставляющих мне объекты учеников и объекты классов. Как я могу правильно объявить эти объекты и массивы и как я могу опубликовать их обратно в моем приложении spring?

Что у меня есть на данный момент:

Возвращается мой API на localhost: 8080 / api / students / populated в серверной части:

 [
    {
        "id": 8,
        "name": "john",
        "classes": [
            {
                "id": 1,
                "name": "math"
            },
            {
                "id": 2,
                "name": "english"
            }
        ]
    },
    {
        "id": 9,
        "name": "paul",
        "classes": [
            {
                "id": 1,
                "name": "math"
            },
            {
                "id": 3,
                "name": "science"
            }
        ]

    }
]
  

Возвращается мой API на localhost:8080/api/classes / populated в серверной части:

 [
    {
        "id": 1,
        "name": "math"
    },
    {
        "id": 2,
        "name": "english"
    },
    {
        "id": 3,
        "name": "science"
    }
]
  

и это мой интерфейс

Student.ts

 import { Classes} from "./classes";

export class Student{
    id: number;
    name: string;
    classes: Classes[];
}
  

Правильно ли я объявляю классы как массив внутри Student?

Classes.ts

 export class Classes{
    id: number;
    name: string;
}
  

create-form.component.html

 <h3>Create Student</h3>
<div [hidden]="submitted" style="width: 400px;">
  <form (ngSubmit)="onSubmit()">
    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" id="name" required [(ngModel)]="student.name" name="name">
    </div>    
    <div class="form-group">
      <label for="classes">Classes</label>
      <select class="form-control" id="classes" name="classes" required [(ngModel)]="student.classes">
        <option *ngFor="let class of classes | async"> {{ class.name }}</option>
      </select>
    </div> 
    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</div>
  

create-form.component.ts

 student: Student= new Student();
classes: Observable<Classes[]>;
submitted = false;
constructor(private studentService: StudentService) { }
ngOnInit() {
    this.classes= this.studentService.getClassesList();
}
onSubmit() {
    this.submitted = true;
    this.save();
}
save() {
    this.studentService.createStudent(this.student)
      .subscribe(data => console.log(data), error => console.log(error));
    this.student= new Student();
}

  

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

 HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: "OK", url: "http://localhost:8080/api/students/create", ok: false, …}
error:
error: "Bad Request"
message: "JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of VALUE_STRING token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of VALUE_STRING token ...
path: "/api/students/create"
status: 400
  

Кто-нибудь может мне помочь и объяснить, что я делаю не так? Кроме того, есть ли какой-либо другой вариант для выбора многих классов в форме? В настоящее время я могу выбрать только один!


Обновление ответа на @ashish.gd Это предварительный просмотр моей сетевой вкладки, когда я публикую без привязки ngmodel в классах

 {id: 8, name: "johnny", classes: null"}
id: 8
classes: null
name: "johnny"
  

И это заголовок моей вкладки network

 Request URL: http://localhost:8080/api/students/create
Request Method: POST
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: http://localhost:4200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
Provisional headers are shown
Accept: application/json, text/plain, */*
Content-Type: application/json
Origin: http://localhost:4200
Referer: http://localhost:4200/add
  

Комментарии:

1. student Объект, который вы отправляете на сервер, содержит classes свойство типа array . Скорее всего, ваш сервер не ожидает такого формата ввода. Попробуйте сделать JSON.stringify(this.student) перед отправкой на сервер.

2. @ashish.gd если я удалю [(ngModel)]="student.classes" из моего выбора, я смогу опубликовать свой student объект без каких-либо ошибок, я просто получу null в своем classes свойстве

3. Можете ли вы опубликовать http-запрос или тело запроса, как показано на вкладке сеть

4. @ashish.gd Да, я обновил сообщение информацией, которую вы просили, как предварительным просмотром, так и заголовком

Ответ №1:

select html-элемент привязывает выбранное значение к student.classes , которое в основном является простой строкой. Из-за этого ваш объект запроса создается с классами в виде строки. Например:

 {
    id: 8,
    name: "johnny",
    classes: "science"
}
  

где в качестве конечной точки вашего API ожидается, что classes свойство будет списком или массивом.

Следовательно, JSON parse error: Cannot deserialize instance of java.util.ArrayList out of VALUE_STRING token;

Изменение вашего объекта запроса на передачу classes свойства в виде массива должно устранить вашу ошибку. Пример:

 {
    id: 8,
    name: "johnny",
    classes: ["science"]
}
  

Однако перенос выбранных элементов в массив невозможен простым привязыванием. Вам нужно будет преобразовать classes свойство из строки в массив, прежде чем создавать api в компоненте.

Комментарии:

1. Благодаря этому ответу я смог сосредоточиться на своей реальной проблеме. Я создал массив из своего объекта, подписавшись на него, затем я использовал этот массив для отображения данных на странице.