24

I'm new to Angular2. I have a JSON object, as below:

var options = {
  param1: "parama1",
  param2: "parama2",
  param3: "parama3"
};

which should convert to query string and append to an external URL to redirect the page like below:

ngOnInit(){
     window.location.href = someurl?param1=param1&param2=param2&param3=param3;
}

I'm looking for a way to convert it to query string. In JQuery, $.param() and in AngularJS $httpParamSerializerJQLike() are there for this. I'd searched, but I got nothing. I want to know is there any way to do it in angular2.

Sivaprasad derangula
  • 1,169
  • 4
  • 12
  • 29

5 Answers5

64

A more 'official' method without the string concats:

import {URLSearchParams} from '@angular/http'
let options = {
  param1: "param1",
  param2: "param2",
  param3: "param3"
};

let params = new URLSearchParams();
for(let key in options){
    params.set(key, options[key]) 
}

console.log("http://someUrl?" + params.toString());

This does automatic encoding by the way.

MikeOne
  • 4,789
  • 2
  • 26
  • 23
8

This solution will work with most complex types

Incase anyone was wondering how to do this, I've written an extension that should work with c# .Net Core 1.1 and Typescript 2.2.2 WebApi which looks like so.

Remember to include these two imports where you are using it as well

import { URLSearchParams } from '@angular/http';
import 'rxjs/add/operator/map'

export class QueryStringBuilder {
    static BuildParametersFromSearch<T>(obj: T): URLSearchParams {
        let params: URLSearchParams = new URLSearchParams();

        if (obj == null)
        {
            return params;
        }

        QueryStringBuilder.PopulateSearchParams(params, '', obj);

        return params;
    }

    private static PopulateArray<T>(params: URLSearchParams, prefix: string, val: Array<T>) {
        for (let index in val) {
            let key = prefix + '[' + index + ']';
            let value: any = val[index];
            QueryStringBuilder.PopulateSearchParams(params, key, value);
        }
    }

    private static PopulateObject<T>(params: URLSearchParams, prefix: string, val: T) {
        const objectKeys = Object.keys(val) as Array<keyof T>;

        if (prefix) {
            prefix = prefix + '.';
        }

        for (let objKey of objectKeys) {

            let value = val[objKey];
            let key = prefix + objKey;

            QueryStringBuilder.PopulateSearchParams(params, key, value);
        }
    }

    private static PopulateSearchParams<T>(params: URLSearchParams, key: string, value: any) {
        if (value instanceof Array) {
            QueryStringBuilder.PopulateArray(params, key, value);
        }
        else if (value instanceof Date) {
            params.set(key, value.toISOString());
        }
        else if (value instanceof Object) {
            QueryStringBuilder.PopulateObject(params, key, value);
        }
        else {
            params.set(key, value.toString());
        }
    }

}

This is working for all the complex types I've used so far.

Edit UrlSearch Parameters has been removed. Here is the updated changes via @NuryagdyMustapayev's gist:

static buildParametersFromSearch<T>(obj: T): HttpParams {
    let params: HttpParams= new HttpParams();

    if (obj == null)
    {
        return params;
    }

    return QueryStringBuilder.populateSearchParams(params, '', obj);
}

private static populateArray<T>(params: HttpParams, prefix: string, val: Array<T>): HttpParams {
    for (let index in val) {
        let key = prefix + '[' + index + ']';
        let value: any = val[index];
        params = QueryStringBuilder.populateSearchParams(params, key, value);
    }
    return params;
}

private static populateObject<T>(params: HttpParams, prefix: string, val: T): HttpParams {
    const objectKeys = Object.keys(val) as Array<keyof T>;

    for (let objKey of objectKeys) {

        let value = val[objKey];
        let key = prefix;
        if (prefix) {
            key += '[' + objKey + ']';
        } else {
            key += objKey;
        }

        params = QueryStringBuilder.populateSearchParams(params, key, value);
    }
    return params;
}

private static populateSearchParams<T>(params: HttpParams, key: string, value: any): HttpParams {
    if (value instanceof Array) {
        return QueryStringBuilder.populateArray(params, key, value);
    }
    else if (value instanceof Date) {
        return params.append(key, value.toISOString());
    }
    else if (value instanceof Object) {
        return QueryStringBuilder.populateObject(params, key, value);
    }
    else if ('undefined' !== typeof value && null !== value){
        return params.append(key, value.toString());
    }
    return params;
}

Remember to import {HttpParams} from "@angular/common/http";

johnny 5
  • 19,893
  • 50
  • 121
  • 195
  • Just as a note you call using the only public method BuildParametersFromSearch – johnny 5 Sep 06 '17 at 16:19
  • `URLSearchParams` is removed, `HttpParams` is used instead. I updated your code to use `HttpParams` here is the gist: https://gist.github.com/nuryagdym/9fe9ab4b3de3d5738d6f596ecf5db374 – Nuryagdy Mustapayev Jan 12 '21 at 15:23
  • I made a mistake, can you replace `||` in this line `else if ('undefined' !== typeof value || null !== value)` with `&&`, stackoverflow does not let me offer an edit. – Nuryagdy Mustapayev Jan 29 '21 at 12:48
  • Hmm, I changed it but, after reading that, are we sure we want to remove null or undefined values in the first place? Aren't some model binders dependent on the fact that the value has been defined. – johnny 5 Jan 29 '21 at 14:29
  • It does not remove it, it just returns value as it is if `undefined` or `null`. otherwise, I was getting `Cannot read property 'toString' of null/undefined error` – Nuryagdy Mustapayev Jan 30 '21 at 16:06
8

You can use HttpParams

import { HttpParams } from '@angular/common/http';

new HttpParams({fromObject: yourObject}).toString()
lucaswxp
  • 2,031
  • 5
  • 23
  • 34
2

How about this:

ngOnInit(){
    let options = {
      param1: "param1",
      param2: "param2",
      param3: "param3"
    };

    let myQuery = 'http://someurl?'
    for (let entry in options) {
        myQuery += entry + '=' + encodeURIComponent(options[entry]) + '&';
    }

    // remove last '&'
    myQuery = myQuery.substring(0, myQuery.length-1)

    window.location.href = myQuery;
}

myQuery value is ?param1=param1&param2=param2&param3=param3.

AArias
  • 2,558
  • 3
  • 26
  • 36
0

I prefer to not use any library, you can simply use a map function to create it.

So this is what is use for this case:

const params= {
 param1:"value1",
 param2:"value2",
 param2:"value2",
};

const queryStr = Object.keys(params).map((el)=>( `${el}=${params[el]}` )).join("&");

this is the output: param1=value1&param2=value2

Akram Rabie
  • 473
  • 5
  • 11