Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read params from html route structure, pass via props #774

Open
wbern opened this issue Apr 9, 2021 · 18 comments · May be fixed by #1105
Open

Read params from html route structure, pass via props #774

wbern opened this issue Apr 9, 2021 · 18 comments · May be fixed by #1105
Labels
contribution wanted A maintainer wants help on an issue or pull request enhancement A new feature request need more info An issue, pull request, or discussion needs more information

Comments

@wbern
Copy link

wbern commented Apr 9, 2021

It would be really nice and intuitive if single-spa passed down the params from the url (like /settings/:userId/profile resulting a { userId: 123 } object).

This is fairly common among routers, vue-router uses path-to-regexp which looks like a promising package to apply to single-spa-layout as well.

How would we go about doing this?

@joeldenning
Copy link
Member

I agree this would be nice.

This would best be implemented in single-spa, not single-spa-layout, since parsing the route paths and providing props to single-spa applications is done within single-spa. Going to transfer this issue over to single-spa for that reason.

The url paths are converted to regular expressions via single-spa's pathToActiveWhen function. That function converts the string to a regular expression, but doesn't capture the params in a regex capture group. So the first step is to get the regex to capture the params (see this code).

Maybe the best implementation would be to have the application's activity function return an object of url parameters, since it's the activity function that has access to that regex. So instead of calling regex.test(route), we'd call const capturedGroups = regex.exec(route) and then convert the capturedGroups array into an object with named params (see this code). Then after that, we'd modify getProps to call the activity function to get any extra props, and then merge those in with the rest of the props (see this code)

@joeldenning joeldenning transferred this issue from single-spa/single-spa-layout Apr 9, 2021
@MathiasWP
Copy link

MathiasWP commented Aug 11, 2021

Would it be an idea to provide this information via the routing-events that are dispatched by single-spa as well @joeldenning? I have a use case where it would be practical to get an object with the params of the current route from the single-spa:routing-event-event.

@joeldenning
Copy link
Member

I'd be open to adding it to the routing event detail objects. If it's implemented as I suggested above, I think this would be possible since we call the activity functions inside of reroute, which is also where we fire the routing events.

@dsfx3d
Copy link

dsfx3d commented Aug 15, 2021

Is anyone already working on the implementation? I would like to contribute to this ticket if no one has started working on it.

@MathiasWP
Copy link

Is anyone already working on the implementation? I would like to contribute to this ticket if no one has started working on it.

I don't think so. I was keen on taking this issue, but i haven't had time to properly get into it. It would be awesome if you did, because i have some real use cases for this feature! @dsfx3d

@joeldenning
Copy link
Member

I have not worked on this - feel free to do so @dsfx3d!

@dsfx3d
Copy link

dsfx3d commented Aug 16, 2021

Ok guys I'll look into it. Thanks

@dsfx3d
Copy link

dsfx3d commented Aug 17, 2021

@joeldenning we'll have to make the object reactive so that the params stay in sync with the URL in the browser. Is there already some functionality built for reactivity? or we can build something like that from scratch

@joeldenning
Copy link
Member

Hmm that's a good point I hadn't considered, the dynamic portions of route params would need to be updated as navigation occurs, but the application may not go through a mount/unmount lifecycle when that happens.

We could try passing a route params object as props that uses a javascript property getter to dynamically calculate the route params. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

@dsfx3d
Copy link

dsfx3d commented Aug 20, 2021

@joeldenning I think there's one more scenario to consider at this point. I understand that we pass props from single-spa and can use window.location to parse the raw search string into a computed property of props object BUT what if the user is using the hash mode of single-spa-layout. In that case, the query would be behind the hash and we'll have to handle it with a different logic. Do you have any suggestions for this?

@joeldenning
Copy link
Member

window.location.hash has the hash in it - that can be used. I'd suggest looking at the following code, which creates a regular expression from a path string. I don't think the regex currently captures the params in a capture group, but I think it could be modified to do so:

function toDynamicPathValidatorRegex(path, exactMatch) {

@dsfx3d
Copy link

dsfx3d commented Aug 22, 2021

yes but my concern is if there's a way to determine if we are using history mode or hash mode.

@dsfx3d
Copy link

dsfx3d commented Aug 22, 2021

got it I was also considering including URL query as an object in props along with params.

@joeldenning
Copy link
Member

You can tell whether the url path is history mode or hash mode based on whether the path given to single-spa contains a # in it or not. If there's no # in the path given to single-spa, then it's history mode. If there is a #, then it's hash mode. If it has paths both before and after the #, then it's both history and hash mode.

@Ebbele
Copy link

Ebbele commented Jun 16, 2022

@joeldenning First of all, thank you for this great framework. I use it a lot and really start to love it!
But this issue really caught my attention. I think it is really necessary to get the routing parameters in applications.
Since I think here is no more progress I started to implement the suggestions mentioned in #774 (comment).
I personally have not made any public contributions yet, but I am ready to do so now.
I started a new project based on Mithril.js and implemented a reload method in the root component, which can be used by the routing event to trigger the redraw.
Have not tried a Hash route yet, but that might not be a problem.
Maybe there is a better solution. Tried it with unmount / mount but i really think its way to imperfomant to do so.

@eedrah
Copy link
Contributor

eedrah commented Aug 26, 2022

Hi Ebbele, great if you've made progress on this issue! We'd encourage you to submit a PR and reference this issue in it, and then we know that someone is still working on it.

In other news, is anyone still finding this is important to them? Or is everyone just doing their own parameter parsing and that's fine?

@eedrah eedrah added enhancement A new feature request need more info An issue, pull request, or discussion needs more information contribution wanted A maintainer wants help on an issue or pull request labels Aug 26, 2022
@SomethingSexy
Copy link

We have also figured out our own parameter parsing but it would be nice if it was done for us.

@dsfx3d dsfx3d linked a pull request Apr 4, 2023 that will close this issue
@dsfx3d
Copy link

dsfx3d commented Apr 4, 2023

@joeldenning I created a PR. I'm surprised this issue is still open. Please review if this is the correct approach.
There's one missing bit and I'll add that as well once you approve this approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution wanted A maintainer wants help on an issue or pull request enhancement A new feature request need more info An issue, pull request, or discussion needs more information
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants