карта не является функцией rx js angular - PullRequest
0 голосов
/ 28 февраля 2020

Я новичок в RX JS, и я немного пытаюсь заставить работать следующий код. В angular я выполняю вызов REST API, а оставшийся API возвращает массив. Мне нужны только определенные данные из API в моей модели. Я пытаюсь сделать это с RX JS (поэтому не 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() {      

  }
}

Я получаю следующую ошибку

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

1 Ответ

5 голосов
/ 28 февраля 2020

Ваш фиктивный API возвращает ответ в этой структуре:

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

Итак, вы пытаетесь вызвать .map для этого объекта. Вместо этого вы хотите перейти к свойству data. Есть несколько способов сделать это, но я сделаю это просто.

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());
}

Редактировать: я переместил внутреннюю карту из подписки, чтобы, надеюсь, сделать .data навигацию, которую я добавил немного яснее. Кроме того, вы должны возвращать массив DataPackage из getPackages.

Альтернатива

Вы можете использовать оператор pluck в конвейере, поэтому убедитесь, что массив входит в ваш map Rx JS оператор.

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());
}

Какой бы подход вы ни использовали, это просто вопрос вкуса. Ни один из этих методов не является безопасным для типов, поскольку вы имеете дело с внешними данными, поступающими в вашу систему.

...