50

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+?

7 Answers 7

52

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

Sign up to request clarification or add additional context in comments.

7 Comments

this would work but is it not the good practice to use the constructor only for dependency injection and use ngOnInit for all the other work?
It works, but I have to strip the segments that are automatically put based on current component route.
Is there an inverse operation too?
In Angular 8, it outputs now matrix notation: ;foo=a;bar=42
you don't need the router or the serializer (which by the way is also in the router, so you don't need to inject the serializer separatly)
|
35

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/

2 Comments

For navigation it is fine, but I want to construct a URL to fetch some data from an API.
the second method in this answers allow you to create a URL string that you can use anywhere, including API calls
20

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.

1 Comment

As long as we don't need to merge the query params (like with queryParamsHandling) this answer works well.
10

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.

Comments

8

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.

Comments

5

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

Comments

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

1 Comment

I tried this way but if you have special chars inside your query, like quotes, this doesn't work even with escaped quotes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.