2017-08-02 71 views
39

我一直在尋找一種方法將查詢參數傳遞到一個API調用與新的HttpClientModuleHttpClient並且還沒有找到解決方案。用舊的Http模塊,你會寫這樣的東西。Angular 4 HttpClient查詢參數

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

這將導致一個API調用到以下網址:

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

然而,新HttpClientget()方法不具有search財產,所以我想知道從哪裏傳在查詢參數?

回答

78

我最終通過get()函數的intellisense找到它。得到愛intellisense。所以我會在這裏發佈給任何正在尋找類似信息的人。

無論如何,語法幾乎相同,但略有不同。代替使用URLSearchParams(),參數需要初始化爲HttpParams(),並且get()函數內的屬性現在稱爲params而不是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 }) 
} 

其實我更喜歡這種語法作爲其多了幾分參數無關。我還重構了代碼,使其略微更簡化。

getLogs(logNamespace): Observable<any> { 

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

多參數

我意識到我是多麼經常需要多個參數傳遞到一個查詢,所以我想我會加上如何做,以及一個部分。到目前爲止,我發現的最好方法是定義一個Params對象,其中包含我要定義的所有參數。正如Estus在下面的評論中指出的那樣,在This Question中有很多關於如何分配多個參數的很好的答案。

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

多參數具有條件邏輯

我經常這樣做有多個參數的另一件事是允許使用多個參數,而不需要他們在每個呼叫的存在。使用Lodash,它非常簡單,可以有條件地向調用API添加/刪除參數。在Lodash或Underscores或者vanilla JS中使用的確切函數可能取決於您的應用程序,但我發現檢查屬性定義工作得很好。下面的函數只會傳遞參數,這些參數在傳遞給函數的參數變量中具有相應的屬性。

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

第一個片段是錯誤的。 'let params = new HttpParams(); params.set(...)'不會按預期工作。請參閱https://stackoverflow.com/questions/45459532/why-httpparams-doesnt-work-in-multiple-line-in-angular-4-3/45459672#45459672 – estus

+1

我繼續編輯它。應該是現在。謝謝! – joshrathke

+0

@joshrathke你可以添加如何添加標題和參數在一起嗎? –

1

joshrathke是正確的。

In angular.io docs寫爲@ angular/http的URLSearchParams已棄用。相反,您應該使用HttpParams from @ angular/common/http。該代碼與joshrathke寫的代碼非常相似。 對於在一個像對象

{ 
    firstParam: value1, 
    secondParam, value2 
} 

保存例如多個參數,你也可以做

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

如果你需要繼承的屬性然後相應刪除hasOwnProperty。

26

你可以(在版本5+)使用fromObjectfromString構造函數的參數創建HttpParamaters時,使事情變得更簡單

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

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

或:

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

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

真棒小費!這將節省很多代碼。感謝更新。 – joshrathke

+1

這不再需要了。您可以直接將JSON對象傳遞給HttpClient。 'const'= {'key':'value'}'to:'http.get('/ get/url',{params:params})' – danger89

0

搜索類型財產URLSearchParamsRequestOptions類在角度4中被棄用。相反,您應該使用params類型爲的屬性URLSearchParams