From 25712ad664780b0531e89a09eaabbc2afb4124ea Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Wed, 25 Aug 2021 13:37:25 -0400 Subject: [PATCH] Treat all parameters not matching a named route segment as query params (#451) * Add failing tests * Always treat parameters that don't match any route segments as query params * Wip --- src/js/Router.js | 14 +++++++------- tests/js/route.test.js | 9 +++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/js/Router.js b/src/js/Router.js index a8c05a76..8a8e1f3e 100644 --- a/src/js/Router.js +++ b/src/js/Router.js @@ -178,7 +178,7 @@ export default class Router extends String { return { ...this._defaults(route), - ...this._substituteBindings(params, route.bindings), + ...this._substituteBindings(params, route), }; } @@ -201,17 +201,17 @@ export default class Router extends String { * Substitute Laravel route model bindings in the given parameters. * * @example - * _substituteBindings({ post: { id: 4, slug: 'hello-world', title: 'Hello, world!' } }, { post: 'slug' }); // { post: 'hello-world' } + * _substituteBindings({ post: { id: 4, slug: 'hello-world', title: 'Hello, world!' } }, { bindings: { post: 'slug' } }); // { post: 'hello-world' } * * @param {Object} params - Route parameters. - * @param {Object} bindings - Route model bindings. + * @param {Object} route - Route definition. * @return {Object} Normalized route parameters. */ - _substituteBindings(params, bindings = {}) { + _substituteBindings(params, { bindings, parameterSegments }) { return Object.entries(params).reduce((result, [key, value]) => { - // If the value isn't an object, or if it's an object of explicit query - // parameters, there's nothing to substitute so we return it as-is - if (!value || typeof value !== 'object' || Array.isArray(value) || key === '_query') { + // If the value isn't an object, or if the key isn't a named route parameter, + // there's nothing to substitute so we return it as-is + if (!value || typeof value !== 'object' || Array.isArray(value) || !parameterSegments.some(({ name }) => name === key)) { return { ...result, [key]: value }; } diff --git a/tests/js/route.test.js b/tests/js/route.test.js index d3fc3ee4..ef3bc1b8 100644 --- a/tests/js/route.test.js +++ b/tests/js/route.test.js @@ -489,6 +489,15 @@ describe('route()', () => { same(route('posts.show', [1, 2]), 'https://ziggy.dev/posts/1?2='); same(route('posts.show', ['my-first-post', 'foo', 'bar']), 'https://ziggy.dev/posts/my-first-post?foo=&bar='); }); + + test("can automatically append object with only 'extra' parameters to query", () => { + // Route has no parameters, the entire parameters object is 'extra' and should be used as the query string + same(route('hosting-contacts.index', { filter: { name: 'Dwyer' } }), 'https://ziggy.dev/hosting-contacts?filter[name]=Dwyer'); + }); + + test("can append 'extra' object parameter to query", () => { + same(route('posts.show', { post: 2, filter: { name: 'Dwyer' } }), 'https://ziggy.dev/posts/2?filter[name]=Dwyer'); + }); }); describe('has()', () => {