Really great article. This is really inspiring and you had some very fine solutions to some potentially hard problems. Good job.
This is awesome Richard. Especially your setup with variations for fast-slow-no connection with Task is great. Thanks for sharing!
Awesome! And you wrote the whole thing in 5 hours!
This is very informative. I think this definitely deserves a mention on Elm roadmap under "How do I make a single page app".
haha I didn't actually write the whole thing in 5 hours 😄 - I just didn't want to publish it until it was done, so I developed it locally and then copied everything over at the last minute after creating the repo. 😉
(It actually took closer to a week.)
This is so amazing, Richard.
Thanks for the nice example, I'm borrowing some ideas for my open source Elm SPA I'm developing as I'm still a Elm newbie.
But I'm wondering about the use of Task,map instead of Cmd.batch, it seems that causes all requests to be done in sequence instead of in parallel. For example the list of articles and the list of tags are loaded after each other instead of in parallel. Is there anyway to fix that and keep using Tasks?
Not yet, but I expect there will be something in Http to parallelize HTTP requests in the future.
Since it's just a performance optimization and performance is fine as-is, I thought it'd be prematurely optimization to go out of my way to use Cmd.batch instead, but in a world where I can parallelize via Http I'd reach for that instead of Task.map2 assuming it would be an easy upgrade. :)
Could detail a little bit your build process ?
(I couldn't find any real ressources on the build process for elm apps)
Checking your app you use elm-live, but I couldn't find how elm-live would do gzipping.
Does this mean in production, you rely on the server to gzip files ?
Also, since the css was provided to you, you didn't need to build it or do anything with it. There could be another advantage of a build tool. Do you use elm-live at NoRedInk too ? (I couldn't find anywhere, where you could customize, minify and gzip the css with elm-live)
Hello, thanks a lot for the great article.
I have a question regarding handling a lot of messages in the Main file for update section: type Msg = SetRoute (Maybe Route) | HomeLoaded (Result PageLoadError Home.Model) ...
Imagine that you have a lot of these messages (in our example we have 32 messages, and 31 of them are like HomeLoaded (Result PageLoadError Home.Model) .. and HomeMsg Home.Msg)
And here we have a problem with building our app - it takes up to 50 seconds to build app.
Could you help us? Could you give us some help?
There's a bug in the 0.18 compiler that has a big performance regression when you have case-expressions with many branches (as I recall, 32 is where it kicks in). The bug will be fixed in 0.19, but in the meantime you can split some of the messages out into a separate union type just to split the one big case-expression into two case-expressions.
Does that make sense? Happy to elaborate if it's unclear!
Thanks for posting this. I am currently working on an SPA, and I have run into scaling problems with my update function and model. Your example shows exactly how to split update and the model across pages, and how to solve some other problems I have seen. This is the example needed to go past the good but simple intro material and to a real application.
Thanks for sharing! It's really great and it's already answered a lot of my questions :)
Just one thing that I noticed is that Main.elm file is getting long and things like ProfileLoaded and etc are residing there.
Is there a way to forward updates to its own sub module?
This is great.
I was thinking about doing the init thing for pages that return a task, but I was a bit stuck because I use remotedata, and it's sendRequest wrapper.
You, sir, are a gem!
Can't wait for the tests :)
Thanks so much for this, great resource, in fact a bit of a life-saver for my current project!
Great article & great job!
Thank you very much
This is badass, 🙏