Как передать параметр запроса в http get

Я хочу добавить параметр запроса, чтобы получить URL-адрес в angular, мой параметр запроса

filter={"page_name":{"_eq":"login"},"environment":{"_eq":"staging"}}

куда нужно закодировать

filter=%7B%22page_name%22%3A%7B%22_eq%22%3A%22login%22%7D%2C%22environment%22%3A%7B%22_eq%22%3A%22staging%22%7D%7D

Это сторонний API, и запрос POST не может быть сделан.

Мой угловой код выглядит следующим образом

const urlString: URLEncode = {
      filter: {
        page_name: { _eq: pageName },
        environment: { _eq: environment.name },
      },
    };
    const paramString = encodeURIComponent(JSON.stringify(urlString.filter));

    const params = new HttpParams().set(
      'fields',
      'page_name,block_name,id,block_content'
    );
    const staticContent$: Observable<DirectusList> = this.http
      .get<DirectusList>(
        `${this.apiService.directusURL}content?filter=${paramString}`,
        { params }
      );

Я не уверен, что это правильный способ сделать или нет, но это работает. Но я не хочу использовать 2 метода, таких как создание параметров http, также добавляющих URL-адрес, вместо этого я хочу добиться этого с помощью httpParams.

Пожалуйста, дайте мне знать, есть ли простой механизм для достижения этого.


person Kartheek s    schedule 02.12.2020    source источник


Ответы (1)


Не проверяя ничего конкретного, я бы сказал, что вам не нужно делать половину той работы, которую вы выполняете. HttpClient вполне способен принимать полные объекты в качестве параметров - другой вопрос, адекватно ли он их URLEncodes (надеюсь, что да).

Пока у вас есть объект filter, вы должны иметь возможность напрямую поместить его в микс, где клиент должен обрабатывать его JSON, и еще много чего:


const filter = {
  page_name: { _eq: pageName },
  environment: { _eq: environment.name },
};


let params = new HttpParams();
params = params.set('fields', 'page_name,block_name,id,block_content');
params = params.set('filter', filter);

const embarkStaticContent$: Observable<DirectusList> = this.http
  .get<DirectusList>(
    `${this.apiService.directusEmbarkURL}embark_content`,
    { params }
);

Редактировать: Хм, кажется, вы не можете просто дать ему filter как объект - я думаю, что быстрое исправление действительно для JSON.stringify(filter).

Однако в качестве другого примера — вот версия, которую я использовал в нескольких проектах — обертка вокруг HttpClient, так что мы не взаимодействуем с ней напрямую, и она обрабатывает все мельчайшие детали, о которых вам не о чем беспокоиться. примерно каждый раз, когда вы делаете какой-либо запрос API.

Удалены различные сообщения журнала и, таким образом, можно игнорировать службы уведомлений и регистраторов и еще много чего, основной механизм здесь:

/*
  Example usage:
      ...get('controller/action', { param1: 123, param2: 'secondParam' })
  Produces the request:
      "baseUrl/controller/action?param1=123&param2=secondParam"
*/
public get<T>(apiResource: string, queryParams?: any): Observable<ActionResponsePayloadDto<T>> {
  const url = this.constructUrl(apiResource);

  return this.httpClient.get<ActionResponsePayloadDto<T>>(url, { params: this.encodeQueryParams(queryParams) })
      .pipe(catchError((err) => this.handleError(err, this.notification, this.logger, this.logSystems)));
}

// Handle transforming any data types as required here for the query
// params before being turned into HttpParams objects
private encodeQueryParams(queryParams: any): HttpParams {
  let result = new HttpParams();

  if (!queryParams) { return result; }

  Object.keys(queryParams).forEach((key: string) => {
    let val = queryParams[key];

    if (this.objectHelper.isDate(val)) {
      val = val.toIsoString();
    }

    result = result.set(key, val);
  });

  return result;
}

Единственное, что мы действительно делаем, это преобразуем любые отправляемые даты в строку формата ISO. Никакой другой строки не происходит, поэтому я не понимаю, почему он будет жаловаться на то, что ваш объект filter был предоставлен как объект...

Редактировать № 2: О, но другой проект не использует эту оболочку, вот пример использования ее параметра с необработанным HttpClient:

public getAlert(alertHash: string): void {
  const sub = this.http.get(this.alertUrl, {params: {alertHash}})
    .subscribe((response: DeviceDetailsAlertDto) => {
      sub.unsubscribe();
      this.emit(this.alertObs, response);
      },
      (err: any) => {
        sub.unsubscribe();
        console.error(`Error retreiving alert details: ${err}`);
        this.emit(this.alertObs, undefined);
      });
}

Я подозреваю, что, возможно, не стоит играть с объектом HttpParams, если вам это не нужно. Я думаю, что простое объединение параметров запроса в один объект может сработать?

const queryParams = {
  fields: 'page_name,block_name,id,block_content',
  filter: {
    page_name: { _eq: pageName },
    environment: { _eq: environment.name },
  }
};

const staticContent$: Observable<DirectusList> = this.http
  .get<DirectusList>(
    `${this.apiService.directusURL}content`,
    { params: queryParams }
  );
person Krenom    schedule 02.12.2020
comment
@Krenon Я получаю ошибку времени компиляции Argument of type 'Filter' is not assignable to parameter of type 'string'. - person Kartheek s; 03.12.2020
comment
@Kartheeks Я отредактировал свой ответ для вас; дайте мне знать, как это происходит. - person Krenom; 03.12.2020