Десериализация объекта переписывает все значения - PullRequest
0 голосов
/ 18 декабря 2018

Допустим, я получаю список продуктов из базы данных и пытаюсь десериализовать данные, используя класс ниже:

export class Product 
{
    constructor() { this.CartQuantity = 1 }

    Id: number;
    Name: string;
    Price: number;
    CartQuantity: number;
}

База данных содержит только Id, Name и Price, тогда как CartQuantity существует только в проекте.Если я десериализую так:

products: Product[];

getProducts() {
   this.ProductService.getAllProducts(
     (response) => {
        this.products = response;
     }
  );
}

CartQuantity тогда не определено для каждого продукта.Единственное решение, о котором я знаю, - это добавить цикл for после получения ответа для установки его в 1. Но если у меня много функций, которые извлекают похожие данные, добавление цикла к каждой из них кажется плохим способом сделать это.Есть ли другой способ сделать это похожим на то, что конструктор установил его автоматически?

Редактировать: вот сервисная функция, которая извлекает данные:

getAllProducts(
    onSuccess,
    onFail = (reason) => console.log(reason)) {
      var url = SOME_URL;
      var req = this.httpClient.get(url);
      var promise = req.toPromise();

      promise.then(
        onSuccess,
        onFail
      );
    }

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вы должны добавить цикл в любом случае, когда вы получаете ответ в своем обещании или когда вы назначаете ответ для продуктов.Я добавляю этот ответ, потому что я видел, что вы не создаете экземпляр класса Product для присвоения products. Это означает, что products: Products[] на самом деле не будет содержать Product объектов, а скорее будет {id: number, name: string, price: number} объект Javascript (среда выполненияназначение).Если в вашем классе Product есть какой-то метод, и вы пытаетесь получить доступ к нему с помощью, скажем, this.products[0].someMethod(), вы получите ошибки.

Вы должны сделать это вместо этого:

getProducts() {
   this.ProductService.getAllProducts(
     (response) => {
        this.products = response.map((eachResponse) => {
            let newProd = new Product();  // anyway you are setting the default value as 1
             // can avoid this loop by directly assigning the props here.
            for (let key in eachResponse) { 
                newProd[key] = eachReponse[key];
            }
            return newProd 
        })
     });
}
0 голосов
/ 18 декабря 2018

Используйте оператор map, чтобы изменить объект и присвоить значение CartQuantity

var req = this.httpClient.get(url);
req.pipe(
   map(item => {
      item.CartQuantity = 1
   })
)
...