How to use multiple, comma separated route params in Vue router - url

I want to set up a route that can take optional params x and y, both of which can be multiple.
The issue I am facing is that vue router only seem to be able to extract actual route segments (delimited by /) into single items in the resulting route.params array:
// For a single route parameter
path: '/route/:x*'
// Given a URL like '/route/foo/bar' the route.params will be:
['foo', 'bar']
// However, a given route like '/route/foo,bar will result in:
['foo, bar']
Similarly, navigating to this route via router.push({ name: 'route', params: { collection: ['foo', 'bar'] }}), the resulting route will still be slash rather than comma separated.
Ultimately, best case scenario would be a pattern in the lines of:
path: '/route/:x*/:y*'
Where both x and y are optional and can be disambiguated via prefixes, e.g.:
path: 'route/:x(foo_.*)?/:y(bar_.*)?'
In turn,
/route,
/route/foo_123,
/route/foo_123,foo_456,
/route/foo_123/bar_123 and
/route/bar_123
will all route to the same location and the router will provide the params in this fashion:
params: {
x: ['foo_123', ...],
y: ['bar_456', ...]
}
I tried a couple of approaches using custom regex as described in the documentation. Unfortunately though, it does not provide any example of multiple optional route params.

Related

How to use URL parameters with router in Vaadin Fusion?

I tried to follow the guide at
Question, which results in a
mobx.esm.js?4fd9:2362 [mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: 'Reaction[MainView.update()]' TypeError: Expected "item" to be a string
My configuration is
path: 'item/:item',
component: 'item-view',
Is there an example, how to solve this? Do I need to handle this in the MainView (I follow the todo-tutorial on vaadin.com?
The problem is that main-view.ts in the starter project has logic which tries to list all navigation routes to generate links for them. Currently that logic is not smart enough to detect and skip routes that have non-optional route parameters.
The error is thrown from router.urlForPath(viewRoute.path) when the path has non-optional route parameters because here we are not specifying what the value for the route parameter should be (for the generated URL). For generating a URL for the path 'item/:item' it would need to do something like router.urlForPath('item/:item', { item: 'my-item' }).
The quick fix (to remove the title from the route definition) suggested by Marcus works because the main-view.ts has logic to skip all routes that don't have a title. You could change that logic to also skip by some other criteria or you could try to include values for the route parameters there (for specific routes) if you really want to generate working navigation links for those routes.
Other alternative would be to mark the route parameter as optional (in case you want the route also to be accessible without a parameter) by adding a question mark after it, then the link can be generated without specifying a value for the parameter.
{
path: 'item/:item?', // <- optional route parameter
component: 'item-view',
title: 'Hello World',
}
It seems you have run into an issue with the starter. In main-view.ts, it loops over the routes with a title and tries to create a link for each in the menu:
${this.getMenuRoutes().map(
(viewRoute) => html`
<vaadin-tab>
${viewRoute.title}
</vaadin-tab>
`
)}
However, router.urlForPath() breaks when there is a URL parameter definition instead of an actual parameter (items/:item instead of items/2).
A quick fix for this would be to remove the title property from your route configuration for any route that has a parameter.
{
path: 'item/:item',
component: 'item-view'
// make sure there is no title here
}

URL helpers can't recognize additional custom dynamic segments in routes

I am using Rails 4.2. In a gem, there is a route defined as
get 'book/:id', to: 'book#show', as: book
I'd like to add an additional dynamic segment in a custom route, so in the routes.rb file in my app, I have
get ':language/book/:id', to: 'book#show', as: language_book
Then in my controller, I tried to call the url helper
language_book_url language: :en, id: 3
I expect to get a url like http://host:port/en/book/3, however, instead, I get http://host:port/book/3?language=en. It seems I can't use the helper with that extra custom dynamic segment. Is it possible to get the desired path with the new dynamic segment variable? Thanks!
usmanali gave a answer in the comment, to use language_book_url :en, 3. But what if I want a mixture of dynamic segments and query string params? So my target url is http://host:port/en/book/3?barcode=1234. How can I call the url helper? A call to the helper like language_book_url('en', 3, barcode: 1234) would produce http://host:port/book/3?language=en&barcode=1234, instead of the expected one.

Url params encoding

I have a route like this
/api/service/:id
But id is a string like name.of.something
So the the url will look like:
/api/service/name.of.something?other=parameters
The controller can't parse that request correctly because of dots.
How should I decode the id to pass it to the route?
You need to add a constraints option to the route that will cause it to accept periods. Note that this will break Rails' automatic format detection, so you will have to pass an explicit ?format=json to the URL if you specifically need format selection.
get "api/service/:id", to: "some#endpoint", constraints: {id: /[[:alnum:]_\.-]+/i}
Adjust the regex to your preference.

Symfony2. Problems with custom URLs. Urlencoding

I have following route in my bundle
/{category}
And I have category with name
Category/Brand
If url is something like this:
domain.com/Company/Brand
then I get error 500 about / symbol.
But if in twig I do
company.name|url_encode()
then I get
Company%2F%Brand
(Code might be wrong, dont remember right now)
But nevertheless Symfony tells me that there is no route matching
And gives me 404.
How can I solve this problem?
Are all your category names like that one or only some of them?
If all of them follow this structure, you could change the route to:
/{company}/{brand}
And change the corresponding controller to accept two variables instead of one. Later you can concatenate them or do whatever you need with them
If only some of them have this structure, you could try to replace the directory separator with some character combination in the controller which creates the link and then reverse this replacement in the controller for this route. For example, in the controller for the template where the link is shown you could
$nameEncoded = str_replace ('/','%%%%',$companyName);
pass this variable to the template and use it to generate the link and then in the receiving controller do:
$nameDecoded = str_replace ('%%%%','/',$companyName);
If your route is /{category} and the URL that you type is domain.com/Company/Brand, the error is normal.
You have to config your route in routing.yml like this:
Company/{category}
Ok!
I found a solution here.
#PUBLICATION URL
###_publication:
pattern: /{username}/{category}/{publicationid}
defaults: { _controller: ###:Default:publication }
requirements:
_method: GET
category: .+
username: .+
publicationid: \d+
#CATEGORY - should be at very end, to match all other URLS
###_category:
pattern: /{category}
defaults: { _controller: ###:Default:category }
requirements:
_method: GET
category: .+

Pass URLs as parameters in Rails

This is kind of strange.
I have a route:
match "program/:program_id" => "program#details"
When calling this, everything works:
/program/1
However, the program IDs I use aren't digits only. They're in fact URLs like so: crid://blah.com/d1e5
How can I pass an URL via a RESTful approach as a paramter?
Calling this doesn't work, obviously:
/program/crid://blah.com/d1e5
/program/crid%3A%2F%2Fblah.com%2Fd1e5
Use program/*program_id instead of program/:program_id.
RFC 1738 says:
... only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL.
So if you are trying to put a URL into the URL, you will either have to put up with the encoded characters because the colon : is not an allowed character except as the protocol seperator, and because a double slash // is not allowed except at the root of the URL, or you have to drop the protocol and the root from your URL and start with the domain. That is:
You can either do this:
/program/crid%3A%2F%2Fblah.com%2Fd1e5
or this
/program/blah.com/d1e5
A compromise when using Rails could be putting the protocol into a URL segment like so:
/program/crid/blah.com/d1e5
which you can collect in your params array with
match "program/:protocol/*program_id" => "program#details
The *program_id segment collects(globs) the rest of the url into a single entry in the params array.
you can recombine this in your controller if needed:
url = "#{params[:protocol]://#{params[:program_id]}}"
so that:
# GET /program/crid/blah.com/d1e5
params[:protocol] #=> "crid"
params[:program_id] #=> "blah.com/d1e5"
url = "#{params[:protocol]://#{params[:program_id]}}"
#=> "crid://blah.com/d1e5"

Resources