Angular: преобразование данных API в новый тип данных в многоразовом/чистом методе

Я пытаюсь преобразовать ответ API в совершенно другую модель представления для нескольких компонентов.

a) Одним из решений является сопоставление/передача данных непосредственно в прокси-сервер API, однако тогда прокси-сервер API не очень подходит для повторного использования, если мне просто нужны простые необработанные данные API.

б) Этот шаблон модель-адаптер может не работать, так как в примере адаптер создает тот же тип объекта данных, что и API. https://florimond.dev/blog/articles/2018/09/using-apis-in-angular-the-model-adapter-pattern/ . Наш конвертер данных, представленный ниже, дает совершенно другой результат.

Ищите другие хорошие решения.

Обычный API:

export class ProductService {
  private readonly apiUrl = environment.baseUrl + '/api/CalculateProducts/';
  constructor(private httpClient: HttpClient) { }

  getProductData(
    productValuationDtoRequest: ProductValuationDtoRequest
  ): Observable<ProductValuationResponse>  {
    return this.httpClient.request<ProductValuationResponse>('post', this.apiUrl,
      {body: productValuationDtoRequest}
    );
  }
}

Конвертер данных:

export class CalculateProductModelService {
  constructor() { }

  convertData(
    productValuationResponse: ProductValuationResponse): CalculateCostModel  {

    const calculateProductModel: CalculateProductModel = {
      valuationAttribute: productValuationResponse?.productValuationDetail[0]?.productValuationAttribute?.description,
      livingAreaQuantity: productValuationResponse?.productValuationDetail[0]?.quantity,
      livingAreaRate: productValuationResponse?.productValuationDetail[0]?.improvementUnitValue * 1.03,
      livingAreaValue: productValuationResponse?.productValuationDetail[0]?.attributeTotalImprovementValue,
      numberOfUnits: productValuationResponse?.numberOfUnits * 2,
      replacementCostNew: productValuationResponse?.replacementCostNew,
      goodPercentage: productValuationResponse?.percentageGood,
      goodValue: productValuationResponse?.replacementCostNew * (100 - productValuationDto?.percentageGood) / 100,
      total: productValuationResponse?.totalImprovementValue
    };
    return calculateProductModel;
  }

person Community    schedule 19.09.2020    source источник
comment
Вы должны начать принимать ответы на свои вопросы или, по крайней мере, оставить комментарий к ответам, которые вы считаете неприемлемыми.   -  person Akash    schedule 21.09.2020


Ответы (1)


Если я правильно понимаю проблему, я бы добавил метод к ProductService для возврата модели, чтобы ProductService в конечном итоге имел 2 метода: один для необработанных данных API и один для модели.

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

Код будет выглядеть так

export class ProductService {
  private readonly apiUrl = environment.baseUrl + '/api/CalculateProducts/';
  constructor(private httpClient: HttpClient, 
     private productModelService: CalculateProductModelService) { }

  getProductData(
    productValuationDtoRequest: ProductValuationDtoRequest
  ): Observable<ProductValuationResponse>  {
    return this.httpClient.request<ProductValuationResponse>('post', this.apiUrl,
      {body: productValuationDtoRequest}
    );
  }

  getProductModel(
    productValuationDtoRequest: ProductValuationDtoRequest
  ): Observable<CalculateProductModel>  {
    return this.getProductData(productValuationDtoRequest).pipe(
      map(rawData => productModelService.convertData(rawData))
    );
  }
}

В приведенном выше примере я использую внедрение зависимостей для внедрения CalculateProductModelService в ProductService. Таким образом, CalculateProductModelService не зависит от http-вызовов и может быть легко протестировано.

person Picci    schedule 19.09.2020