Các tham số truy vấn httpClient 4 góc


145

Tôi đã được tìm kiếm một cách để vượt qua truy vấn thông số vào một cuộc gọi API với mới HttpClientModule's HttpClientvà vẫn chưa tìm ra giải pháp. Với Httpmô-đun cũ, bạn sẽ viết một cái gì đó như thế này.

getNamespaceLogs(logNamespace) {

    // Setup log namespace query parameter
    let params = new URLSearchParams();
    params.set('logNamespace', logNamespace);

    this._Http.get(`${API_URL}/api/v1/data/logs`, { search: params })
}

Điều này sẽ dẫn đến một lệnh gọi API tới URL sau:

localhost:3001/api/v1/data/logs?logNamespace=somelogsnamespace

Tuy nhiên, HttpClient get()phương thức mới không có thuộc searchtính, vì vậy tôi tự hỏi nên chuyển ở đâu trong các tham số truy vấn?


2
Với Angular 7, bạn có thể viết thông số của mình dưới dạng đối tượng và sử dụng nó như thế này: this.httpClient.get(url, { params } Kiểm tra stackoverflow.com/a/54211610/5042169
Jun711

Câu trả lời:


229

Tôi đã kết thúc việc tìm kiếm nó thông qua IntelliSense trên get()chức năng. Vì vậy, tôi sẽ đăng nó ở đây cho bất cứ ai đang tìm kiếm thông tin tương tự.

Dù sao, cú pháp gần giống nhau, nhưng hơi khác nhau. Thay vì sử dụng URLSearchParams()các tham số cần phải được khởi tạo HttpParams()và thuộc tính trong get()hàm bây giờ được gọi paramsthay vì search.

import { HttpClient, HttpParams } from '@angular/common/http';
getLogs(logNamespace): Observable<any> {

    // Setup log namespace query parameter
    let params = new HttpParams().set('logNamespace', logNamespace);

    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, { params: params })
}

Tôi thực sự thích cú pháp này vì nó là một thông số bất khả tri hơn một chút. Tôi cũng đã cấu trúc lại mã để viết tắt hơn một chút.

getLogs(logNamespace): Observable<any> {

    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, {
        params: new HttpParams().set('logNamespace', logNamespace)
    })
}

Nhiều tham số

Cách tốt nhất mà tôi đã tìm thấy cho đến nay là xác định một Paramsđối tượng với tất cả các tham số tôi muốn xác định được xác định bên trong. Như @estus đã chỉ ra trong bình luận dưới đây, có rất nhiều câu trả lời tuyệt vời trong Câu hỏi này về cách gán nhiều tham số.

getLogs(parameters) {

    // Initialize Params Object
    let params = new HttpParams();

    // Begin assigning parameters
    params = params.append('firstParameter', parameters.valueOne);
    params = params.append('secondParameter', parameters.valueTwo);

    // Make the API call using the new parameters.
    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, { params: params })

Nhiều tham số với logic có điều kiện

Một điều khác tôi thường làm với nhiều tham số là cho phép sử dụng nhiều tham số mà không yêu cầu sự hiện diện của chúng trong mỗi cuộc gọi. Sử dụng Lodash, thật đơn giản để thêm / xóa các tham số khỏi các cuộc gọi đến API một cách có điều kiện. Các hàm chính xác được sử dụng trong Lodash hoặc Underscores hoặc vanilla JS có thể khác nhau tùy thuộc vào ứng dụng của bạn, nhưng tôi đã thấy rằng việc kiểm tra định nghĩa thuộc tính hoạt động khá tốt. Hàm bên dưới sẽ chỉ truyền các tham số có thuộc tính tương ứng trong biến tham số được truyền vào hàm.

getLogs(parameters) {

    // Initialize Params Object
    let params = new HttpParams();

    // Begin assigning parameters
    if (!_.isUndefined(parameters)) {
        params = _.isUndefined(parameters.valueOne) ? params : params.append('firstParameter', parameters.valueOne);
        params = _.isUndefined(parameters.valueTwo) ? params : params.append('secondParameter', parameters.valueTwo);
    }

    // Make the API call using the new parameters.
    return this._HttpClient.get(`${API_URL}/api/v1/data/logs`, { params: params })

6
Đoạn đầu tiên là sai. let params = new HttpParams(); params.set(...)sẽ không làm việc như mong đợi. Xem stackoverflow.com/questions/45459532/ khăn
Estus Flask

@joshrathke Bạn có thể vui lòng thêm cách thêm tiêu đề và thông số vào nhau không?
Savad KP

3
@SavadKP bạn có thể đặt chúng như thế này.http.get (url, {headers: headers, params: params}); và đọc về các httpHeaders mới như HttpParams
Junaid

Tôi đoán new HttpParams({fromObject: { param1: 'value1', ... }});là cách tiếp cận dễ nhất (góc 5+) sau đó params.set(...).
Pankaj Prakash

88

Bạn có thể (trong phiên bản 5 +) sử dụng fromObjectfromString thông số constructor khi tạo HttpParamaters để làm cho mọi việc dễ dàng hơn một chút

    const params = new HttpParams({
      fromObject: {
        param1: 'value1',
        param2: 'value2',
      }
    });

    // http://localhost:3000/test?param1=value1&param2=value2

hoặc là:

    const params = new HttpParams({
      fromString: `param1=${var1}&param2=${var2}`
    });

    //http://localhost:3000/test?paramvalue1=1&param2=value2

27
Điều này không còn cần thiết nữa. Bạn chỉ có thể truyền trực tiếp một đối tượng JSON cho HttpClient. const params = {'key': 'value'}đến: http.get('/get/url', { params: params })
nguy hiểm89

7
@ nguy hiểm89 Đúng. Nhưng được cảnh báo: chỉ cho phép các giá trị chuỗi hoặc chuỗi []!
Jose Enrique

Tiết kiệm số lượng lớn thời gian của tôi. Tôi đã xây dựng url bằng cách nối các tham số truy vấn dưới dạng chuỗi vào url yêu cầu.
Pankaj Prakash

16

Bạn có thể vượt qua nó như thế này

let param: any = {'userId': 2};
this.http.get(`${ApiUrl}`, {params: param})

3
Đúng nhưng điều đó ném ra ngoài cửa sổ
DanLatimer

@DanLatimer Bạn không cần phải sử dụng bất kỳ, vì vậy bạn có thể tiếp tục sử dụng cách gõ cho đến khi bạn chuyển nó đếnparams
InDieTasten

11

Một giải pháp ngắn gọn hơn:

this._Http.get(`${API_URL}/api/v1/data/logs`, { 
    params: {
      logNamespace: logNamespace
    } 
 })

6

Với Angular 7, tôi đã làm cho nó hoạt động bằng cách sử dụng các mục sau mà không cần sử dụng HttpParams.

import { HttpClient } from '@angular/common/http';

export class ApiClass {

  constructor(private httpClient: HttpClient) {
    // use it like this in other services / components etc.
    this.getDataFromServer().
      then(res => {
        console.log('res: ', res);
      });
  }

  getDataFromServer() {
    const params = {
      param1: value1,
      param2: value2
    }
    const url = 'https://api.example.com/list'

    // { params: params } is the same as { params } 
    // look for es6 object literal to read more
    return this.httpClient.get(url, { params }).toPromise();
  }
}

4

Nếu bạn có một đối tượng có thể được chuyển đổi thành {key: 'stringValue'}cặp, bạn có thể sử dụng phím tắt này để chuyển đổi nó:

this._Http.get(myUrlString, {params: {...myParamsObject}});

Tôi chỉ thích cú pháp lây lan!


3

joshrathke là đúng.

Trong tài liệu angular.io được viết rằng URLSearchParams từ @ angular / http không được dùng nữa . Thay vào đó, bạn nên sử dụng HttpParams từ @ angular / common / http . Mã này khá giống và giống với những gì joshrathke đã viết. Đối với nhiều tham số được lưu ví dụ trong một đối tượng như

{
  firstParam: value1,
  secondParam, value2
}

bạn cũng có thể làm

for(let property in objectStoresParams) {
  if(objectStoresParams.hasOwnProperty(property) {
    params = params.append(property, objectStoresParams[property]);
  }
}

Nếu bạn cần các thuộc tính được kế thừa thì hãy xóa hasOwnProperty cho phù hợp.


2

thuộc tính tìm kiếm của loại URLSearchParams trong lớp RequestOptions không được dùng ở góc 4. Thay vào đó, bạn nên sử dụng thuộc tính params của loại URLSearchParams .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.