Skip to content

Commit

Permalink
fix(matcher): merge params
Browse files Browse the repository at this point in the history
Fix #189
  • Loading branch information
posva committed Apr 22, 2020
1 parent e878e91 commit d8a6b25
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
45 changes: 45 additions & 0 deletions __tests__/matcher/resolve.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,36 @@ describe('RouterMatcher.resolve', () => {
assertErrorMatch({ path: '/', components }, { name: 'Home' })
).toMatchSnapshot()
})

it('merges params', () => {
assertRecordMatch(
{ path: '/:a/:b', name: 'p', components },
{ name: 'p', params: { b: 'b' } },
{ name: 'p', path: '/a/b', params: { a: 'a', b: 'b' } },
{
params: { a: 'a' },
path: '/a',
matched: [],
meta: {},
name: undefined,
}
)
})

it('only keep existing params', () => {
assertRecordMatch(
{ path: '/:a/:b', name: 'p', components },
{ name: 'p', params: { b: 'b' } },
{ name: 'p', path: '/a/b', params: { a: 'a', b: 'b' } },
{
params: { a: 'a', c: 'c' },
path: '/a',
matched: [],
meta: {},
name: undefined,
}
)
})
})

describe('LocationAsRelative', () => {
Expand Down Expand Up @@ -822,6 +852,21 @@ describe('RouterMatcher.resolve', () => {
)
})

it('merges params', () => {
assertRecordMatch(
{ path: '/:a/:b?', name: 'p', components },
{ params: { b: 'b' } },
{ name: 'p', path: '/a/b', params: { a: 'a', b: 'b' } },
{
name: 'p',
params: { a: 'a' },
path: '/a',
matched: [],
meta: {},
}
)
})

it('throws if the current named route does not exists', () => {
const record = { path: '/', components }
const start = {
Expand Down
27 changes: 23 additions & 4 deletions src/matcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,13 @@ export function createRouterMatcher(
})

name = matcher.record.name
// TODO: merge params with current location. Should this be done by name. I think there should be some kind of relationship between the records like children of a parent should keep parent props but not the rest
// needs an RFC if breaking change
params = location.params || currentLocation.params
params = {
...paramsFromLocation(
currentLocation.params,
matcher.keys.map(k => k.name)
),
...location.params,
}
// throws if cannot be stringified
path = matcher.stringify(params)
} else if ('path' in location) {
Expand All @@ -227,7 +231,9 @@ export function createRouterMatcher(
currentLocation,
})
name = matcher.record.name
params = location.params || currentLocation.params
// since we are navigating to the same location, we don't need to pick the
// params like when `name` is provided
params = { ...currentLocation.params, ...location.params }
path = matcher.stringify(params)
}

Expand Down Expand Up @@ -256,6 +262,19 @@ export function createRouterMatcher(
return { addRoute, resolve, removeRoute, getRoutes, getRecordMatcher }
}

function paramsFromLocation(
params: MatcherLocation['params'],
keys: string[]
): MatcherLocation['params'] {
let newParams = {} as MatcherLocation['params']

for (let key of keys) {
if (key in params) newParams[key] = params[key]
}

return newParams
}

/**
* Normalizes a RouteRecordRaw. Transforms the `redirect` option into a `beforeEnter`
* @param record
Expand Down

0 comments on commit d8a6b25

Please sign in to comment.