Ошибка при добавлении параметров запроса в запрос http - PullRequest
1 голос
/ 07 июня 2019

Я использую фиктивные данные и InMemoryDbService, как показано на примере тура героев.Загрузка данных работает нормально, когда я не передаю HttpParams.После добавления параметров я получаю ответ 500 со следующей ошибкой в ​​теле: {error: "collection.filter is not a function"} Я заполнил свою таблицу данными из запроса на получение следующим образом:

Код компонента:

@Component({
  selector: 'app-adapter',
  templateUrl: './adapter.component.html',
  styleUrls: ['./adapter.component.css']
})
export class AdapterComponent implements OnInit {
  dataSource = new MatTableDataSource<Request>();
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatPaginator) paginator: MatPaginator;
  constructor(private api: BaseServiceApi) {}

  ngOnInit() {
    this.refresh(); // this works with no params and populates my table
  }

  refresh(params?) {
    this.getRequests(params)
      .subscribe(reply => {
          this.dataSource.data = reply.payload as Request[];
          this.dataSource.sort = this.sort;
          this.dataSource.paginator = this.paginator;
          this.pageSize = this.paginator.pageSize;
        }
      );
  }

  getRequests(params?): Observable<ServerReply> {
    console.log(params);
    return this.api.get("requests", params);
  }

  processSearch() { // here is where I am submitting a form and trying to get new response

    if (this.searchForm.invalid)
      return;

    // these params are not fields of ServerReply or request but are filters
    let params = new HttpParams({fromObject: this.searchForm.getRawValue()});
    this.refresh(params); // this is submitting with params and throwing exception
  }

}

API-сервис:


import { Injectable } from '@angular/core';
import {Observable, of, pipe} from "rxjs";
import {HttpClient, HttpParams} from "@angular/common/http";
import {catchError} from "rxjs/operators";
import {ServerReply} from "../../models/server-reply";

@Injectable({
  providedIn: 'root'
})
export class BaseServiceApi {

  apiUrl: string;

  constructor(private http: HttpClient) {
  }

  get(path: string, params?: HttpParams): Observable<ServerReply> {
    return this.http.get<ServerReply>(this.apiUrl + path, {params})
      //.pipe(catchError(this.handleError<ServerReply>(path, new ServerReply()))
      //);
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(operation + ": " + JSON.stringify(error)); // log to console instead

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }

}

ServerReply:

export class ServerReply {

  alerts: [];

  payload: [];

}

Запрос:

export class Request {
  id: number,
  // other fields omitted

}

Ложная служба данных:

@Injectable({
  providedIn: 'root'
})
export class MockDataService implements InMemoryDbService {

  createDb() {
    let requests = this.createRequests(1000);
    return {requests};
  }

  private createCloudRequests(count: number) {
    // returns one ServerReply with a Request[] in ServerReply.payload
  }
}

Не уверен, что я делаю не так.Я попытался добавить параметры запроса в тур по примерам героев, и это работает (даже несуществующие поля героя не выдают ошибку, как это).

импорт модуля приложения:

imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    MaterialModule,
    AppRoutingModule,
    HttpClientModule,
    HttpClientInMemoryWebApiModule.forRoot(MockDataService, {dataEncapsulation: false}),
    ReactiveFormsModule,
  ]

1 Ответ

1 голос
/ 07 июня 2019

Проблема заключалась в том, что по умолчанию InMemoryDbSerivce ожидает, что все в объекте db будет массивом.Он просто попытается применить фильтр на основе моих параметров запроса.

Я нашел решение, просмотрев примеры в github: https://github.com/angular/in-memory-web-api/blob/master/src/app/hero-in-mem-data-override.service.ts

Здесь я смог перехватить запрос get и применить свою собственную фильтрацию, используя предоставленные мной параметры запроса

макет службы:

import {InMemoryDbService, RequestInfo, STATUS} from 'angular-in-memory-web-api';

@Injectable({
  providedIn: 'root'
})
export class MockDataService implements InMemoryDbService {
  ...

  // intercept get method for all in memory requests.
  get(reqInfo: RequestInfo) {
    let queryParams: Map<string, string[]> = reqInfo.query;
    console.log(queryParams);

    if (queryParams.size > 0) // if no params are passed, Map exists but is empty
      return this.handleFilterRequest(reqInfo, queryParams); // custom Response built here

    // return request as passthrough if no params
    return undefined;
  }

}

...