Angular HttpClient Get method with body

前端 未结 4 1465
一整个雨季
一整个雨季 2020-12-15 16:57

I\'m improving an existing API, and the requirement is to provide a single get method which can accept multiple search criteria and based on those criteria perform the query

相关标签:
4条回答
  • 2020-12-15 17:22

    As far as I can tell you cannot use HttpClient get to send a body. You could use the query at least for it to be idiomatic. (Or you can try to force the issue somehow).

    Lets say you have an array with your criteria:

    const criteria = [ {a: 25}, {b: 23} ];
    http.get(url + '/?criteria='+ encodeURIComponent( JSON.stringify(criteria)));
    

    Sending a body in a GET request is a violation of some RFC standard, and even though it might work you're bound to summon some arcane demons.

    0 讨论(0)
  • 2020-12-15 17:25

    In the service method, you can have your method like below which takes the optional parameters for the search query. And you can send your search parameter over Observe as below.

    getAllSubscribers(
        page?,
        itemsPerPage?,
        userParams?
      ): Observable<PaginatedResult<Subscribers[]>> {
        const paginatedResult: PaginatedResultSubscribers[]> = new PaginatedResult<
          Subscribers[]
        >();
    
        let params = new HttpParams();
    
        if (page != null && itemsPerPage != null) {
          params = params.append("pageNumber", page);
          params = params.append("pageSize", itemsPerPage);
        }
    
        if (userParams != null) {
          params = params.append("minAge", userParams.minAge);
          params = params.append("maxAge", userParams.maxAge);
            }
    
           return this.http
          .get<Subscribers[]>(this.baseUrl + "/subscribers", { observe: "response", params })
          .pipe(
            map(response => {
              paginatedResult.result = response.body;
              if (response.headers.get("Pagination") != null) {
                paginatedResult.pagination = JSON.parse(
                  response.headers.get("Pagination")
                );
              }
              return paginatedResult;
            })
          );
      }
    

    The basic idea is the use of HttpParams.

    0 讨论(0)
  • 2020-12-15 17:26

    To make Amir's answer some more generic I have done the following to build params for the passed item.

    To my generic data service I have added this variant:

    // Get data for passed parameters or item containing filters
    public getByItem<T>(apiMethod: string, item?: T, apiParms?: HttpParams): Observable<T> {
        if (!apiParms) apiParms = new HttpParams();
        if (item) {
            const keys = Object.keys(item) as Array<keyof T>;
            for (let key of keys) {
                apiParms = apiParms.append(key.toString(), item[key].toString());
            }
        }
        // Call generic method of data service
        return this.get<T>(apiMethod, apiParms); // => return this.http.get<T>(environment.apiUrl + apiMethod, { headers: this.defaultHeaders
    
    0 讨论(0)
  • 2020-12-15 17:40

    This worked for me:

    import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; 
    
    filterBooks(category: string, year: string): Observable<Book[]> {
       let httpHeaders = new HttpHeaders()
                             .set('Accept', 'application/json');
       let httpParams = new HttpParams()
                            .set('category', category)
                        .set('year', year);
       console.log(httpParams.toString());
       console.log(httpHeaders.keys());
       return this.http.get<Book[]>(this.bookUrl, {
                    headers: httpHeaders,
                    params: httpParams, 
                    responseType: 'json'
            });
    } 
    
    0 讨论(0)
提交回复
热议问题