简体   繁体   English

地图不是函数 rxjs angular

[英]map is not a function rxjs angular

I'm new to RXJS and I'm struggling a bit to get the following code to work.我是 RXJS 的新手,我正在努力使以下代码正常工作。 In angular I'm doing a call to a REST API and the rest API returns an array.在 angular 中,我正在调用 REST API,其余 API 返回一个数组。 I only need certain data from the API in my model.我只需要模型中 API 的某些数据。 I'm trying to do this with RXJS (so no forEach, ...) and this is what I have so far:我正在尝试使用 RXJS 来做到这一点(所以没有 forEach,...),这就是我到目前为止所拥有的:

import { Injectable, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DataPackage } from './models/data-package';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class PackageService implements OnInit{

  constructor(private http: HttpClient) { }

  getPackages(): Observable<DataPackage> {
    return this.http
    .get<any>('http://dummy.restapiexample.com/api/v1/employees')
    .pipe(
      map((data: any[]) =>
        data.map(
          (response: any) =>
            new DataPackage(response.employee_name, response.employee_salary, response.employee_age, new Date())
        )
      )
    );
  }

  ngOnInit() {      

  }
}

I'm getting the following error我收到以下错误

ERROR TypeError: "data.map is not a function"
    getPackages package.service.ts:19

Your mock API is returning a response in this structure:您的模拟 API 正在以这种结构返回响应:

{
  "status": "success",
  "data": [
    { /.../ }
  ]
}

So you are trying to call .map on this object.所以你试图在这个对象上调用.map Instead you want to navigate to the data property.相反,您希望导航到data属性。 There are a couple of ways of doing this, but I'll keep it simple.有几种方法可以做到这一点,但我会保持简单。

getPackages(): Observable<DataPackage[]> {
  return this.http
    .get<any>('http://dummy.restapiexample.com/api/v1/employees')
    .pipe(
      map((response: any) => response.data // <--- navigate to "data"
        .map((item: any) => this.mapResponseItem(item))            
    );
}

private mapResponseItem(item): DataPackage {
  return new DataPackage(response.employee_name, 
    response.employee_salary, response.employee_age, new Date());
}

Edit: I moved the inner map out of the subscribe to hopefully make the .data navigation I added a little clearer.编辑:我将内部地图移出订阅,希望使我添加的.data导航更清晰一点。 Also, you should be returning an array of DataPackage from getPackages .此外,您应该从getPackages返回一个DataPackage数组。

Alternative选择

You can use the pluck operator in the pipe so ensure an array comes into your map RxJS operator.您可以使用pluck运营商在管道这样确保阵列进入你的map RxJS运营商。

getPackages(): Observable<DataPackage[]> {
  return this.http
    .get<any>('http://dummy.restapiexample.com/api/v1/employees')
    .pipe(
      pluck('data'), // <-- pass "data" on to map
      map((data: any) => data.map(item => this.mapResponseItem(item))            
    );
}

private mapResponseItem(item): DataPackage {
  return new DataPackage(response.employee_name, 
    response.employee_salary, response.employee_age, new Date());
}

Whichever approach you use is just a matter of taste.无论您使用哪种方法,都只是品味问题。 Neither method is typesafe as you're dealing with external data coming in to your system.当您处理进入系统的外部数据时,这两种方法都不是类型安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM