How to map an http .get observable response to handle object of arrays or array of objects

问题描述 投票:0回答:1

我的代码在下面,它希望端点采用这样的项目数组的形式

[{},{},{}...]

[
  {
    "id": 1,
    "name": "item1"
  },
  {
    "id": 1,
    "name": "item2"
  }
]

但是有些端点使用根节点标识符/标签,如

{[{},{},{}...]}

{
 "items": [
  {
    "id": 1, 
    "name": "item1"
  },
  {
    "id": 1, 
    "name": "item2"
  }
 ]
}

为了处理后一种情况,我添加了“startNode”参数。例如,在上面的第二个 JSON 中,代码期望传入“items”作为 startNode。我想重构可观察到的响应,以便它自动处理两种格式而无需知道 startNode:

getEndpoint(event: CustomEvent) {
  const mappedValues = mapValuesKeyBy(event.detail, 'name', 'value');
  let endpoint = trim(mappedValues._endpoint) || 'http://localhost:4100/states';
  const labelKey = trim(mappedValues._labelKey);
  const valueKey = trim(mappedValues._valueKey);
  const labelFormat = mappedValues._labelFormat;
  const hiddenColumns = trim(mappedValues._hiddenColumns);
  const startNode = trim(mappedValues._startNode);

  this.appService.get(endpoint, {}).subscribe(result => {
    
    if(typeof(result[0]) === 'undefined' && result[startNode]) {
      result = result[startNode];
    } else {
      endpoint = 'http://localhost:4100/states';
    }
    
    const titleMap: TitleMapItem[] = map(result, value => ({
        name: labelFormat ? this.jsf.parseVariables(labelFormat, value) : value[labelKey],
        value: value[valueKey]
      }));
      
    this.setTitleMap(event, titleMap);

    /** NOTE - remaps the original <mat-select> dynamic list to the Properties <mat-autocomplete> for setting the `defaultValue` */
    const tableConfig: AutoCompleteTableConfig = {
      labelKey,
      valueKey,
      hiddenColumns: hiddenColumns || []
    };
    this.setAutoCompleteList(event, result, tableConfig);
  });
}

第一个用例端点的示例在这里: https://jsonplaceholder.typicode.com/users

第二个用例端点的示例在这里:https://dummyjson.com/products

json angular rxjs observable
1个回答
0
投票

正确输入你的端点可能更好,但你可以这样做:

this.appService.get(endpoint, {}).subscribe(result => {
    if (!Array.isArray(result)) {
        result = Object.values(result)[0];
    }
    
    // ...
});

首先检查

result
是否是数组,如果不是,则取第一个对象值

当然,这里假设你只有数组和单键对象。就像我说的,最好正确输入你的端点。

© www.soinside.com 2019 - 2024. All rights reserved.