首页 > 解决方案 > 将http响应映射到角度7中的接口

问题描述

我有角度购物模板,我正在尝试将用于我的后端的购物车服务连接起来,所以我已经这样做了,但是为了使数据库中的事情更容易,我不得不将对我的后端的请求从 更改为{quantity, amount, product}{quantity, amount, productId}所以我没有必须将整个产品存储在数据库中并且到目前为止它工作正常,现在当我得到响应时,我想将它映射到它的界面,但首先我需要找到具有响应中的 id 的产品,我是如果我拥有整个产品,则能够映射响应,但我又不想将产品保存在我的数据库中。这是我的映射代码,但我在调用按 id 查找产品的函数时遇到问题:

this.getAllProducts().pipe(map(p => p.map((s): CartItem => ({
  currency: s.currency,
  product: this.productService.getProduct(s.product).subscribe(p => p),
  quantity: s.quantity,
  selectedColor: s.selectedColor,
  selectedSize: s.selectedSize,
  userId: s.userId
}))));


  private getAllProducts(): Observable<CartResponse[]> {
    return this.http.get<CartResponse[]>('http://localhost:8082/cart/getAllItems?userId=111').pipe(
      map(o => o.map((sp): CartResponse => ({
        quantity: sp.quantity,
        currency: sp.currency,
        product: sp.product,
        selectedColor: sp.selectedColor,
        selectedSize: sp.selectedSize,
        userId: sp.userId
      }))));
  }


export interface CartResponse {
    product: string;
    quantity: number;
    selectedSize: any;
    selectedColor: string;
    currency: string;
    userId: string;
}

export interface CartItem {
    product: Product;
    quantity: number;
    selectedSize: any;
    selectedColor: string;
    currency: string;
    userId: string;
}

标签: angularhttprxjsangular-httpclient

解决方案


您可以使用以下方法,请注意我创建了一些带有假数据的工厂方法以对其进行测试。您可以将它们替换为您的实际实现:

import { of, Observable } from 'rxjs';
import { map, mergeMap, toArray } from 'rxjs/operators';

export interface Product {
  id: string;
  name: string;
}

export interface CartResponse {
  product: string;
  quantity: number;
  selectedSize: any;
  selectedColor: string;
  currency: string;
  userId: string;
}

export interface CartItem {
  product: Product;
  quantity: number;
  selectedSize: any;
  selectedColor: string;
  currency: string;
  userId: string;
}

const fakeGetAllProducts = (): Observable<CartResponse[]> => of<CartResponse[]>([
  { currency: "US", product: "PX1", quantity: 10, selectedColor: "red", selectedSize: "L", userId: "UX1" },
  { currency: "EU", product: "PX50", quantity: 10, selectedColor: "blue", selectedSize: "S", userId: "UX2" }
]);
const fakeGetProduct = (id: string): Observable<Product> => of<Product>({ id, name: `Product ${id}` });

// Here the cart response is destructured into 2 values: the product id and everything else
const mapResponseToItem = ({ product, ...noProduct }: CartResponse): Observable<CartItem> => fakeGetProduct(product).pipe(
  map<Product, CartItem>(product => ({ ...noProduct, product }))
);

fakeGetAllProducts().pipe(
  // flatten the array in order to process single items from it sequentially
  mergeMap(items => items),
  // map a cart response into a cart item observable and flatten it
  mergeMap(mapResponseToItem),
  // collect the sequentially processed elements into an array
  toArray()
).subscribe(console.log);

您可以看到在这次闪电战中运行的代码


推荐阅读