Anirudh Sridhar
Anirudh Sridhar

Reputation: 183

React Router sending nested object as query

I am using router.push to update my url using the following code:

data = {url: 'abc', id: 1234}
this.props.router.push(
    path: 'app/p/1',
    query: {search: data}
)

However, this sets the query to: ?search=%5Bobject+Object%5D.

I have even tried using jQuery param to convert nested objects to query but react router parses the query as a normal string

data = {url: 'abc', id: 1234};
search = $.param({search: data});
this.props.router.push(
    path: 'app/p/1',
    query: search
)

This results in the query being set to:

0=s&1=e&10=i&11=t&12=e&13=_&14=u&15=r&16=l&17=%25&18=5&19=D&2=a&20=%3D&21=a&22=b&23=c&24=d&3=r&4=c&5=h&6=%25&7=5&8=B&9=s

EDIT

The value of data is generated dynamically and is not fixed. It will always be a key: value pair.

EDIT 2

I would like to replicate the filter functionality used here. All the filters are implemented inside the q object. For example, a search for username would be q[username]=abcd

I would like to set the query as: search[url]=abc&search[id]=123 which would mean: search%5Burl%5D=abc&search%5Bid%5D=123 in terms of the URL.

How can this be achieved?

Upvotes: 0

Views: 2403

Answers (2)

William Martins
William Martins

Reputation: 2067

First, I'll refer to react-router v3 docs to answer your question:

I don't know what react-router version you're using, but it should be the same to v2 and v4

https://github.com/ReactTraining/react-router/tree/v3.0.5/docs

The router#push method:

You can check that router#push uses a string or a location descriptor.

This location descriptor, when using an object, uses a Query object.

So, if you want to use the location descriptor object, your method should be like this:

let data = { url: 'abc', id: 1234 };

this.props.router.push({
    path: 'app/p/1',
    query: data
});

Using a string as query string:

If you want to pass a custom string (it may help you), you need to use search, that receives a QueryString.

Why you're having problems:

react-router expects the query object to be passed as key:value, I think it isn't able to handle the nesting cases.

What you can do:

You can use the awesome qs module to handle that:

const qs = require('qs');

let data = { url: 'abc', id: 1234 };
let query = qs.stringify({ search: data }); // produces: 'search%5Burl%5D=abc&search%5Bid%5D=1234'

this.props.router.push({
    path: 'app/p/1',
    search: query
});

Upvotes: 2

Win
Win

Reputation: 2133

Try this:

let data = { url: 'abc', id: 1234 };

let query = [];

for (key in data) {
  query.push(`${key}=${data[key]}`);
}

search = query.join('&');

this.props.router.push(
    path: 'app/p/1',
    search: `?${search}`
)

Upvotes: 0

Related Questions