43

I am trying to create a URL from an object in an Angular 5 SPA. My code looks like the following:

import { UrlTree, UrlSegmentGroup, DefaultUrlSerializer, UrlSegment } from "@angular/router";

const urlTree = new UrlTree();
urlTree.root = new UrlSegmentGroup([new UrlSegment("EndPoint", {})], {});
urlTree.queryParams = {
  "param1": param1Value,
  "param2": param2Value
};
const urlSerializer = new DefaultUrlSerializer();
const url = urlSerializer.serialize(urlTree);

It does the job, but it seems to include significant overhead for such a trivial job and I am wondering if there is a more straightforward method to obtain the url from the object.

My expectation is to have something simple as:

const url = someSerializer.serialize("/segment1/segment2", { 
  "param1": param1Value,
  "param2": param2Value
})

Question: How to create a url string with query parameters from an object in Angular 5+?

Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164

7 Answers7

44

You can use just Router and UrlSerializer:

constructor(private router: Router, private serializer: UrlSerializer) {
  const tree = router.createUrlTree([], { queryParams: { foo: 'a', bar: 42 } });
  console.log(serializer.serialize(tree)); // "/?foo=a&bar=42"
}

See demo: https://stackblitz.com/edit/angular-basic-template-3hx9at?file=src/app/hello.component.ts

martin
  • 93,354
  • 25
  • 191
  • 226
32

You can directly use it in queryParams if you ultimately want to navigate through Angular's routing module.

let params = {
    param1: param1Value,
    param2: param2Value
};
    
this.router.navigate('/segment1/segment2', { queryParams: params });

For static URLs:

const params = new HttpParams()
   .set('param1', param1Value)
   .set('param2', param2Value);

const URL = 'yourEndPoint/segment1/segment2?' + params.toString();

For more details and examples see: https://www.tektutorialshub.com/angular/angular-pass-url-parameters-query-strings/

Shadoweb
  • 5,812
  • 1
  • 42
  • 55
Prachi
  • 3,478
  • 17
  • 34
17

If you already have queryParams: Params, either from building the object yourself or getting it from the current route, you can simply use:

const queryParamsString = new HttpParams({ fromObject: queryParams }).toString();

queryParamsString will be param1=somevalue1&param2=somevalue2&...

Don't forget to prepend the ? to it if you're appending this to some URL.

Andre
  • 538
  • 4
  • 9
  • As long as we don't need to merge the query params (like with `queryParamsHandling`) this answer works well. – Daniel Apr 22 '22 at 16:22
7

In case you want to build an utility to construct a query string from an object, try Angular HttpParams:

// initialize from an object
const obj: any = {
  'number': 123,
  'string': 'lincoln',
  'empty': null,
  'bool': true,
  'array': ['1991', null, 'ramanujan'],
}
let httpParams = new HttpParams({ fromObject: obj })

// append manually
// do not forget to reassign
httpParams = httpParams.append('extra', 'gimme a chance')

console.log(httpParams.toString())

// number=123&string=lincoln&empty=null&bool=true&array=1991&array=null&array=ramanujan&extra=gimme%20a%20chance

Note that HttpParams only accepts key in string and value in string | string[]. Therefore, marking obj as any makes obj valid in code editor. Another note is that HttpParams splits every item in an array into separate parameters with the same name, which might not what you expected.

If you prefer something more "native", URLSearchParams is a candidate. This one supports pretty much the same methods in HttpParams like append, delete, has etc. Syntaxes are slightly less verbose. Every value in object will force toString, so an array results in one parameter only, as opposed to the behavior in HttpParams.

const obj: any = {
  number: 123,
  arr: [999, 'michael'],
  str: 'simp',
  empty1: null,
  empty2: undefined,
  canSleep: false,
}

const searchParams = new URLSearchParams(obj)

// no need to reassign after appending
searchParams.append('more', 'gimme one more kiss')

console.log(searchParams.toString())
// number=123&arr=999%2Cmichael&str=simp&empty1=null&empty2=undefined&canSleep=false&more=gimme+one+more+kiss

URLSearchParams is supported in most modern browsers, Node.js and Web Workers. To use it in IE, please provide a polyfill.

bonniss
  • 445
  • 5
  • 13
7

You can take the same approach as the Angular HttpClient

const url = 'https://example.com'

const params = new HttpParams()
  .set('key1', 'Value 1')
  .set('key2', 'Value 2')

const request = new HttpRequest('GET', url, null, {params});

request.urlWithParams

The advantage of this approach is that the HttpParams class handles URL encoding of the parameters and the HttpRequest handles cases when the URL has existing params or simply has a '?' at the end.

4

Try like this:

  let httpParams = new HttpParams().set('params1', String(id));
  httpParams = httpParams.set('params2', String(name));

  return this.httpClient.get<any>(this.BASE_URL, {
          params: httpParams
        });
Gobu CSG
  • 653
  • 5
  • 7
-4

You can construct a url while making a call to api to fetch data like this:

GetData(id) {

    this.http.get<User>('http://test.com' + id + '/users')
      .subscribe(data => {
        console.log(data)
      });
}
yer
  • 1,454
  • 2
  • 16
  • 33
  • I tried this way but if you have special chars inside your query, like quotes, this doesn't work even with escaped quotes. – Sixteen Feb 23 '21 at 11:46