2017-08-02 70 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