question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Optional path parameters?

See original GitHub issue

In redux-little-router one can specify optional parameters in route paths, e.g. /some/path/(:foo), and then both /some/path and /some/path/hello would map to the same route, in the former case passing { foo: undefined } as the parameters. Is there a similar mechanism in redux-first-router whereby those could both map to the same action but with an optional field in the payload?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:23 (13 by maintainers)

github_iconTop GitHub Comments

24reactions
faceyspaceycommented, Sep 7, 2017

Ok, this is done. All matching capabilities of the path-to-regexp package we use are now supported, except unnamed parameters.

Let’s go through what we now support. Usually it’s best to start with the simplest example, but I think most people looking at this get this stuff. We’ll start with one of the more complicated use cases just to see how far we can take this:

Multi Segment Parameters

So for example, imagine you’re github.com and you’re now using Redux-First Router 😃, and you need to match all the potential dynamic paths for files in repos, here’s how you do it:

const routesMap = {
   REPO: '/:user/:repo/block/:branch/:filePath+'
}

So that will match:

but not:

And if you visit that URL, you will see it in fact doesn’t exist. If it did, you would use an asterisk (for 0 or more matches as in regexes) like so:

const routesMap = {
   REPO: '/:user/:repo/block/:branch/:filePath*'
}

So the above 2 options will match a varying number of path segments. Here’s what a corresponding action might look like:

const action = {
   type: 'REPO',
   payload: {
       user: 'faceyspacey',
       repo: 'redux-first-router',
       branch: 'master',
       filePath: 'src/pure-utils/pathToAction.js'
   }
}

Pretty cool, eh!

The inspiration actually came from a PR I did to CodeSandBox. I didn’t actually implement this there, but I was thinking about it around that time. I.e. that CodeSandBox should have the full file paths in the URLs like github. Currently it’s as a URL-encoded query param, but in the future (perhaps with RFR), they’ll be able to do what Github does as well.

Optional Single Segment Parameters

However, you usually just want to add optional single segment params like this:

const routesMap = {
   ISSUES: '/:user/:repo/issues/:id?'
}

So with that you can visit both:

  • https://github.com/faceyspacey/redux-first-router/issues
  • https://github.com/faceyspacey/redux-first-router/issues/83

Here’s the 2 actions that would match that respectively:

  • const action = { type: 'ISSUES' }
  • const action = { type: 'ISSUES', payload: { id: 83} }

And that’s basically the “80% use-case” most powerful feature here. I.e. when you want to use the same type for a few similar URLs, while getting an optional parameter.

note: you can also have optional params in the middle, eg: /foo/:optional?/bar/:anotherOptional? So all 3 of /foo/bla/bar/baz and /foo/bar/baz and /foo/bar will match 😃

Optional Static Segments (“aliases”)

The absolute most common (and simpler) use case for such a thing is when you want /items and /items/list to have the same type (because they are aliases of each other ). You accomplish it slightly differently:

const routesMap = {
  HOME: '/home/(list)?',
}

or

const routesMap = {
  HOME: '/home/(list)*',
}

Both are the same. It would be nice if you didn’t have to wrap list in parentheses, but you have to. That’s fine. Keep in mind this isn’t a parameter; the 2nd path segment has to be list or not be there.

Also, the common convention we should use is the the question mark ? instead of the asterisk *. We should reserve the asterisk for where it has unique capabilities, specifically the ability to match a varying number of path segments (along with +) as in the initial examples with the github file paths.

Regexes

Another thing to note about the last one is that (list) is in fact a regex. So you can use regexes to further refine what paths match. You can do so with parameter segments as well:

const routesMap = {
  HOME: '/posts/:id(\\d+)',
}

So essentially you follow a dynamic segment with a regex in parentheses and the param will have to match the regex. So this would match:

  • /posts/123 but this wouldn’t:
  • /posts/foo-bar

Multiple Multi Segment Parameters

Last use case: say you want to have multiple params with a varying number of segments. Here’s how you do it:

const routesMap = {
  HOME: '/home/:segments1+/bla/:segments2+',
}

So a url like /home/foo/bar/bla/baz/bat/cat will result in an action like this:

const action = {
   type: 'HOME',
   payload: {
       segments1: 'foo/bar',
       segments2: 'baz/bat/cat'
   }
}

So yes, you can have multiple “multi segments parameters”.

One thing to note is you could also accomplish this like this: HOME: '/home/:segments1(.*)/bla/:segments2(.*)'.


Final reminder: if you do plan to use multi segment parameters, they have to be named. This won’t work: /home/(.*)/bla/(.*).

Well, the truth is it will, and given the previous URL you will have a payload of:

const action = {
   type: 'HOME',
   payload: {
       0: 'foo/bar',
       1: 'baz/bat/cat'
   }
}

But consider that “undefined” functionality. Don’t rely on that. Name your segments! Like any other key in your payload. That’s the goal here. Originally I had the idea of making an array at payload.segments, but then I realized it was possible to name them. So naming all params is the RFR way.


Lastly, to get this do:

yarn upgrade redux-first-router@next
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to define an optional parameter in path using swagger
Determines whether this parameter is mandatory. If the parameter is in "path", this property is required and its value MUST be true. Source: ......
Read more >
Spring Optional Path Variables | Baeldung
In this tutorial, we'll learn how to make a path variable optional in Spring. First, we'll describe how Spring binds @PathVariable parameters in ......
Read more >
Describing Parameters - Swagger
By default, OpenAPI treats all request parameters as optional. You can add required: true to mark a parameter as required. Note that path...
Read more >
Optional path parameters #93 - OAI/OpenAPI-Specification
Quite simply, making path parameters optional changes the path semantics and can make resolution of the operation non-deterministic. I know we can all...
Read more >
How to use React Router with an optional path parameter
To add in an optional path parameter in React Router, you just need to add a ? to the end of the parameter...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found