Advanced Elm

Reuse Solution

Richard Feldman

Richard Feldman

Vendr, Inc.
Advanced Elm

Check out a free preview of the full Advanced Elm course

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

Richard live-codes the solution to the Reuse exercise.


Transcript from the "Reuse Solution" Lesson

>> Richard Feldman: So we have two TODOs in two different places, but they're will essentially wanting to accomplish the same thing. Which is to say, we wanna move this viewPagination function, extract it out of profile and out of home, and move it into PaginatedList. So let's start by putting it here, and PagenatedList.viewPagination is a little bit redundant.

So let's just go ahead and rename that to view, and I'm definitely gonna need to expose this so that those files can call it. What I'm gonna do at this point is since I just wanna make sure that this thing works properly inside of this module. I'm actually just gonna compile that thing alone by itself, I actually it shouldn't bother compiling main.elm because I just wanna see if my paginatedList works probably fast.

It actually doesn't, okay, let see what else we got. There is couple of problems here one is, it's acting like it needs its own message type, but it doesn't have one. Second is that doesn't actually know what an articles is. Okay fair enough, so both of these are potentially solvable by using type variables.

So if we look at our paginatedList here and if we look at how it's actually being used. If I jump through these functions it's okay, I'm calling page on list, I'm calling total on list, am I doing anything else to the list? Looks like not, what do page and total do?

Well, if I look at those functions, one takes a paginatedList of any type variable and returns an int. And total also takes a paginatedList of any type variable and returns an int. So what that means is that I don't actually need this to take an article preview. I can just make it completely unbound.

I can say yeah, I'll view this thing and it's just gonna work out fine, as far as I can tell. Let's see if that's true, okay, so far so good. It just says I can't find the message type. So, it didn't actually complain about that being a problem.

So in other words, the two operations that I'm actually doing on this list, I'm getting the total count which is to say the total number of pages in the paginatedList, and I'm getting the current page in the list. Neither of those has anything to do with what happens to be inside the list.

So it's totally fine for purposes of viewing the actual pagination for us to give it an unbound type variable, and say yeah, if you wanna view this thing, I don’t actually care what’s inside of it. That’s somebody else's job to deal with, I’m just here to render the pagination itself, which only cares about numbers, not about the content itself.

Okay, cool, so, that takes care of that one error. We saw the other one where it says I cannot find a message type. I don’t know what that is, which is fair because the paginatedList itself does not have a message type. And what do I really want to introduce one unless again, I've gone through the motions said, yeah, I concluded base on how this things being used that it really does have so many different message types that I wanna give it on message type.

We're not there yet, let's see if we can do it with that first. Okay, so how's this message actually being used? Well, we have something called ClicksFeedPage. That's clearly a message constructor, a message variance rather. Is there anything else? I don't really see anything, it looks like that's the only one that we actually need.

So we only have this one on click handler and that's the only place where this comes up. So I see that ClickedFeed Page is currently taking targetPage, targetPage is an integer. So what I can do is I can just say, okay, pageLink is going to take an int to message function.

So I'm gonna name toMsg and then I'm just gonna call toMsg instead of that actual message constructor there of ClickedFeedPage.
>> Richard Feldman: Okay, well now pageLink takes the next argument which means I'm no longer able to call it using exactly what I was doing before. So I need to add an extra toMsg in here, I'm just gonna propagate that up and say view needs also to take that as an argument.

>> Richard Feldman: Now, based on that, I extracted this thing from profile, so wherever I was calling ViewPagination, which appears to be only in one place. I now know that that's going to become PaginatedList.view, and I know what the first argument's gonna be. It's ClickedFeedPage, because that's exactly what was there before.

So now, I have made it so that I have successfully deleted this thing out of a profile. I'm now delegating to this reusable thing inside PaginatedList.view. And I'm passing in exactly the same argument that I had before. So based on how I just refactored that code, everything still should work the same way as before.

So let's find out that's true. So I'm gonna build the PaginatedList, and I have a syntax error because I messed up on 107. Right, definitely gonna need an extra arrow there, okay. But I still didn't adjust the type annotation even though, [LAUGH] I made it more flexible but then didn't annotate as such, oops, that's better, okay.

So now the paginatedList compiles, and I can check to see if profile compiles. So I'm gonna do the same thing here. I'm not gonna quite bother compiling the other stuff yet because I just wanna kinda working on those two files that I made adjustments to, and sure enough, they now both compile.

So we've confirmed that number one, profile is the least, from the compiler's perspective, doing what it was doing before. And the logic here is simple enough that I'm pretty confident it is, in fact, doing what it was doing before. But I also now have this nice reusable thing which actually is no third-party dependencies whatsoever.

It's all type valuables, it's got HTML, an int, and PaginatedList, and that's it. Everything else is completely flexible. Cool, so let's see about doing that in the other place, which was the Home page. So inside Home, we have the same TODO as what we had before, and we have the same viewPagination thing that we have right here.

So this time, I'm just gonna go ahead and delete this sucker and do without. So I look at viewPagination, again, that's only called in one place. I'm actually gonna undo that real quick, just long enough to grab this thing right here. So that I don't have to remember it later.

And now, I remember from before, that I'm gonna use that same message that was in the implementation as the first argument to the function now known as PaginatedList.view. Okay, now I'm gonna run the same thing, but I'm gonna run it on the Home page. That worked, and, if that's true, theoretically that was all that was affected by those changes.

So I should be able to compile main, and then sure enough the entire thing compiles. And we have successfully reused this thing that really is the same on both of those pages.

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