Advanced Elm

JavaScript & Review

Richard Feldman

Richard Feldman

Vendr, Inc.
Advanced Elm

Check out a free preview of the full Advanced Elm course

The "JavaScript & Review" Lesson is part of the full, Advanced Elm course featured in this preview video. Here's what you'd learn in this lesson:

When interoperating with JavaScript, Elm or JavaScript be the source of truth. Richard argues ultimately for letting JavaScript own the state because of the consequences of competing for state. This section of the course is also reviewed.


Transcript from the "JavaScript & Review" Lesson

>> Richard Feldman: Now this is a pattern that I'm using with authentication here. But this is a general pattern with JavaScript interop in general. Whenever you're working on an application that needs to interface with JavaScript, whether it's through a port, through a custom element, if you haven't seen Luke Wesley's talk on custom elements, highly recommend that by the way.

Any case where you have stateful JavaScript logic, you gotta decide who's gonna own that state. Either your JavaScript code is going to be subservient to the Elm code and say yeah, you know what, I happen to know this JavaScript code is not doing its own state management. It's going to completely delegate and to entrust all the values that it gets from Elm.

In which case, great, you can say Elm is the source of truth. Whatever's in the model is reality, and that JavaScript code is going to rely on that, and at best, it's going to cache it. Or you can do the reverse. And I think the reverse is a lot more common in practice.

Which is to say, I'm interacting with this JavaScript code. Being JavaScript code, it's probably got its own state. It's probably not a big bucket of pure functions, cuz that's not as normal in JavaScript as it is in Elm. So given that this JavaScript code is already going to manage its own state, all I can do is make it worse if I also separately manage my own state and now have a competing source of truth with JavaScript.

We'll have a much better time if I say, you know what, JavaScript's managing its own state, great. I am just going to listen to what it's got going on. And I'm just gonna do my best to keep my own caches as fresh and unstale as possible, using techniques like this, where we're saying every single time your state changes, I wanna know about it.

I wanna update my cache. I'm not gonna directly mess with my own cache at all. I'm just gonna be a passthrough. All I'm ever gonna do is store the latest value that I heard about from that stateful JavaScript, whatever it might be.
>> Richard Feldman: So by doing this, we can prevent as many of these sort of state synchronization bugs as possible, by sort of thinking in terms of who's the cache, who's the source of truth?

And we want to have as few sources of truth as possible, and have the hierarchy be the one that is the most reliable is sort of at the top, and everybody else is just caching that at best. So to recap, we started off by talking about impossible states that we can end up in.

Multiple sources of truth is one possible way we can do that. We looked at the tab var, where we had each of the tabs potentially thinking that they were the one that was active. And when we shift that to say there's only source of truth, we model each of these tabs as a different variance in a custom type, and all we can have is one source of truth for which one is active.

That prevented that impossible state from happening, which actually did come up in practice before. I talked about derived data, and how when we start off with something that's like a timestamp in the database, it goes through a number of transformations before it makes it all the way to being rendered for the user.

In a lot of cases, we can't avoid caching that in the model, which is fair enough. But if we can, it's best to do that derived data in the view, not storing it in the model where it can potentially end up as a competing source of truth. We talked about authentication and how, again, ultimately the source of truth is on the server.

And if we disagree with the server, we're out of luck. So we're gonna cache stuff for performance reasons, so that we don't have to have the users enter their credentials every single time they wanna do something. But we're gonna be aware that those things are caches. And we're gonna take as many steps as we can to prevent those caches from getting stale by doing things like every time local storage updates, updating the model, and not ever changing the session in the model through any other means other than refreshing that cache.

And finally, we talked about the implications on JavaScript interop. So if we're running into the same situation, where we have something that we're interoperating with on the job description side that is stateful, let it own the state. Treat the Elm stuff as a cache of that state, and trust it for as much state as possible.

Because the consequence of having competing sources of truth is much more severe than the minor inconvenience of having to ask it for its state on a regular basis.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now