-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
Added routing example #195
base: main
Are you sure you want to change the base?
Added routing example #195
Conversation
Hi, thanks for having a go at this, a routing example is needed. There are some issues here that I'm having a look at, the two big ones are:
Routing is becoming a bit of a hot topic at the moment, and I think this library could be part of a solution, but I think there's a more fundamental piece of work to do here to make routing easy for people, which is beyond the scope of this PR. I'm tempted to see if I can make that work first. 🤔 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for having a go at this. I've been travelling today so apologies if any of this comes across as a little blunt. 😄
I'm going to try and tackle the routing problem next since it keeps coming up, and I think this library you're using could be used somewhere in there, and it's an interesting example.
It does however need more work. I fear that if I gave this to the general public, I'd produce more questions than answers in it's current state. 😄
Importantly, you don't need to do that work (yet?) if you don't want to. An example of how to do routing now with the current verison of Tyrian would be great, and there are at least three or four ways to do it that I've seen (all follow the same basic principle, but the details vary). But I do feel like I need to do some work to make this nice and friendly for everyone - at least the core mechanics of it. In that world, I might for example, give you a function you need to define (alongside init
and update
and the others) that is something like def routing(path: String): Page.Msg
, and you could elect to use this url-dsl library to do that, or something else.
examples/routing/src/Main.scala
Outdated
@JSExportTopLevel("TyrianApp") | ||
object HelloTyrian extends TyrianApp[Msg, Model]: | ||
|
||
val homePath = root / "home" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that the first thing someone sees is a 'Not Found', because by default they're going to land on /
, and there are no instructions as to what to do when you get a 404, for example, you could provide links that do work.
examples/routing/src/Main.scala
Outdated
@@ -0,0 +1,127 @@ | |||
package myorg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this has come from a Mill build, and I don't believe you've tested it within the examples project, because sbt won't compile this code. It's in the wrong folder structure and it doesn't work.
examples/routing/src/Main.scala
Outdated
_ => Page.Counter | ||
), | ||
_ => Page.Home | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to say I find this syntax really unfriendly and hard to read - I couldn't recommend it to anyone.
What I would want to see is something like (totally made up):
Path(path) match
case root => Page.Home
case root / "counter" => Page.Counter
case _ => Page.NotFound
I've had a quick look at the library you've pulled in and the closest I can find is this: https://github.com/sherpal/url-dsl/blob/master/url-dsl/src/test/scala/urldsl/examples/RouterUseCaseExample.scala#L71
But here, they're actually making up a mini router of there own in order to get the syntax they want.
examples/routing/src/Main.scala
Outdated
|
||
def init(flags: Map[String, String]): (Model, Cmd[IO, Msg]) = | ||
( | ||
AppState(getPageFromURL(dom.window.location.href), counter = 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preferred pattern here would be to run this side effect in a Cmd
on the line below, and that would instantly trigger and update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your replies! I'm totally new into Elm architecture and don't know best patterns yet. I've updated sbt file. When I posted PR I've wrongly thought that the examples are "ad hoc" meaning that they don't belong to any sbt project. That was because I've only looked at build.sbt
at root directory and didn't found examples
reference. I realized that examples
is sbt
project on its own after your comment :) So sorry for the confusion.
Project now compiles :) Also I added navigation between not found page and home page as a side effect. |
I added custom router built on the bones of |
Hi @DeamonDev - apologies, I'm not ignoring this! I've been a bit under the weather this week and I'm catching up. Also I started this on ... Tuesday? Just before I got sick. It's relevant to your interests: #197 |
Morning @DeamonDev! OK, the Frontend Routing PR has been merged. Should be released in the next day or so and then we can revisit this piece of work and hopefully, hopefully, this will make people very happy. 😄 |
Hi @DeamonDev - Tyrian 0.7.0 is out with basic frontend routing built-in, but I'm keen to update this example to use it, and to use it in conjunction with url-dsl if you're still interested. Do you want to carry on or would you like a hand? Happy to help. 😄 |
Hi @davesmith00000 ! Thanks for info, recently I had very limited time and didnt track the changes. But of course we could try to work on improving this example. |
Great! Let me know if you need anything. 😄 |
@davesmith00000 feel free to edit this example (if you would like to go that route 😅). The change is quite straightforward. Unfortunately my
As I said I have very limited time in the upcoming 2 or 3 weeks and definitely don't have time to battle with broken tooling... |
f39c532
to
758eb90
Compare
Mistyped Scala.js version? |
I'm out of time this morning but I'll try and have a look later. I've kicked off a CI build in the meantime. Thanks! 👍 |
@davesmith00000 yup I misstyped that. It turned out to be my wrong setup. Now its working and I rebased onto main and updated the code :) |
@DeamonDev - I've started refactoring and simplifying but once again I've run out of time. Please review / pull the change. If you've already done something similar or you feel it isn't right, please feel free to push a revert. 😄 There are still some parts that need work and some parts that actually don't seem to work, but I'll get back to it later unless you beat me to it. 😉 I quite like it though! |
Looks great! I admit that my code was somewhat chaotic and now it looks much better. I think the url should be updated while walking on the page. It may be achieved as a side effect in update function, but maybe your new routing solution could take care of that? I’ve just seen you added Nav.pushLink so you can ignore my comment above ^^ |
Still going, pushed another commit, but unfortunately something is not working now. Clearly I broke it, but I'm not sure how and I've run out of time again for today. Any ideas @DeamonDev? |
I also dont have too much time today but I think it may be related to the fact that you're pushing |
Hmmm. So the problem with that notion is that it means you cannot use I'm currently locked in a sort of dread fascination with this thing. I'm making some progress.. I think... by having implemented a custom ...but I have to say I'm increasingly thinking this library may not be worth the hassle. It looks very promising, but I'm finding it difficult to work with for some reason. I suspect I'm just using it incorrectly or something.. I'll have one more go in the morning, I'm suspicious of the recursive function that does the matching. |
I've pushed another change, this now works apart from the back button. For some reason we're getting double entries into the history stack, so pressing back does nothing. If you remove the I've rewritten a lot of the code, but in fact I don't think it was strictly necessary. The main problem that took me ages to work out, was that if one of your routes is just Nearly there... |
@DeamonDev this all works correctly now, if you'd like to take a look. One problem I've noticed is that I've made a choice in the way the routing code works that was perhaps a mistake. Needs some thought, but I'd welcome your opinion: When you click a button, you generate a Msg directly and to have the address bar updated, you then need to use When you use an anchor tag:
Point 2 was meant to be helpful, but now I think the inconsistency is just confusing (it confused me!). In this example I've had to add a new message type to account for navigation from a button vs an anchor tag. I suspect, I should just take out the automagical address bar update and leave you to manage this stuff yourself, to be consistent - because it doesn't just update the address bar but the history too. What do you think? |
My opinion is to be as consistent as possible. Maybe it would be possible to add |
I've added this example for not only educational purposes. Maybe it is good idea to implement routing mechanism in Tyrian using this library? As you can see this is all about sequential folding which could be generalized to
Router[T]
whereT
in this example would bePage
enum.