angularangular-http

Angular HttpParams is there a way to add square brackets to serialized query params when generating query params with the same key?


When querying my api with multiple query params of the same key but multiple values it is not interpreting the request properly unless square brackets are added to each key. Let me give you an example:

    let params = new HttpParams();

    params = params.append('color', 'blue');
    params = params.append('color', 'red');

    console.log(params.toString()) // color=blue&color=red 
    // Would prefer color[]=blue&color[]=red

Is there any way to produce this functionality?


Solution

  • I solved this by writing my own interceptor and generating the query string with another library. Please see below:

    Install this library:

    $ npm i query-string --save
    

    Add this interceptor:

    import {
      HttpEvent,
      HttpHandler,
      HttpInterceptor,
      HttpParams,
      HttpRequest,
    } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import * as querystring from 'query-string';
    
    @Injectable()
    export class QueryParamInterceptor implements HttpInterceptor {
    
      constructor() {}
    
      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
        if (!request.params.keys().length || request.method !== 'GET') {
          return next.handle(request);
        }
    
        let { params } = request;
    
        let queryParams = this.createQueryParams(params);
    
        let queryString = querystring.stringify(queryParams, { arrayFormat: 'bracket' });
    
        let urlWithParams = request.urlWithParams.replace(request.params.toString(), queryString);
    
        request = request.clone({
          url: urlWithParams,
          params: new HttpParams(),
        });
    
        return next.handle(request);
      }
    
      private createQueryParams(params: HttpParams): { [key: string]: string } {
        let queryParams = {};
    
        for (let key of params.keys()) {
          let values = params.getAll(key);
    
          if (!values) {
            continue;
          }
    
          if (values.length === 1) {
            queryParams[key] = values[0];
    
            continue;
          }
    
          queryParams[key] = values;
        }
    
        return queryParams;
      }
    }