Check out a free preview of the full The Hard Parts of UI Development course
The "Understanding the dataToView Function" Lesson is part of the full, The Hard Parts of UI Development course featured in this preview video. Here's what you'd learn in this lesson:
Will begins diagramming the application with the new dataToView function, which will handle all view updates regardless of the user interaction.
Transcript from the "Understanding the dataToView Function" Lesson
[00:00:00]
>> We are building out the same user interface we had before. There it is. I'm typing into my input field, but I first got to click on it, which is gonna remove my default text, what's up? As I type, I get a preview of what I've typed. Very, very simple user interface.
[00:00:16]
However, even that involves a lot of reasoning about back and forth between our data. And if we added ten handlers, the flow between them of what the user's behavior was, I'm gonna have what we saw here. At its core, I'm gonna have so many different places that I can affect what the user sees.
[00:00:36]
I'm gonna have so many different places where I can affect the content that is being viewed by the user. And we are in a high-stakes environment. If what the user sees does not look like what's actually going on and we can't work out why, we're in a really difficult position, because users were brought up from one year old that what they see is how the world actually is under the hood.
[00:01:01]
So they're really upset. Even latency in a server, if you're writing server code errors, a lot of them are gonna be basically blocked before they reach the user, not when it comes to the user in face code. Not only that, it's running on their machine, meaning you've just passed them a bunch of code to execute on their local machine.
[00:01:23]
Meaning it's very hard to track what are the changes, plus we are very well able to test visually what you see as a user on the page. We're in a tough environment, so the more predictable we can make our code, the more we can minimize where changes in what we see you can even happen, the more that I can track through data through some sort of description of how to display it on the page.
[00:01:52]
And then whenever the user takes action not for it to have a bunch of custom changes to what the user sees based on an action but to change only data, and then run that single same converter function, not five different places, but change data and then create the view.
[00:02:13]
That creates a restriction on us as well that every single thing that the user sees must depend on, or all content at least in this case, must depend on some sort of data. Otherwise, how's it even showing up? So we're requiring change to data and all things user sees must be defined first in data.
[00:02:31]
So there's no mysterious thing showing up that are a result of an ad hoc change of what's being displayed in some handler function, but only through stored state posh word for our data that describes, that's where state becomes a really useful term as opposed to a very strange term because it describes the state of the universe.
[00:02:50]
It describes all possible changeable things, in our case, the state of the universe, it'd be like the underlying atoms and where they are in XYZ coordinates of this pen. Same thing here, we have our underlying data describing all possible things about the application that can be displayed and then changed by the user.
[00:03:10]
So let's do it, people. Let's do it. So here we go. Let's put our JavaScript runtime on this side. We have our DOM implemented in C++ here,
>> You're DOM big, and the browser window is full.
>> Yeah, perfect. That's actually brilliant. Yeah, I mean, that's wide enough, right?
[00:03:39]
And then our actual pixels, even this is probably still wasteful, isn't it? Dear. Should I have made it wider? No, that's okay, I think that's okay. There's our output pixels. This is our output pixels. Honestly, it's a rendered image that gets sent to the graphics card 60 times a second.
[00:03:58]
Rasterized image, the layout engine goes where are those elements be positioned on this particular screen size and device type based on the list of elements, all we had to do was add to the C++ list? And then the render engine as a whole is gonna work out the exact pixels as a composite image compositing all those different divs, and images, and honestly, animations happening 60 times a second.
[00:04:22]
That image is then being rasterized, turns a bunch of pixels to be sent to a graphics card to be displayed, okay? And then here is our exactly as we heard there, our DOM, which is a list in our C++ run time and it has initially, what on it?
[00:04:48]
Phil, help me out. What's on it initially? On our C++ DOM here.
>> So we have input or input element. Yeah, input node, input element, exactly. I'm actually gonna put it right on the side here, so that we have lots of room to add its handlers and its value property.
[00:05:08]
We can even put those in now so that we have it ready to go. And then its handlers. Its handlers, that may work. Look at that. That actually makes me really happy.
>> Is handlers. What's our next element, Phil?
>> We have our div elements.
>> Div, and that has some text.
[00:05:32]
Beautiful. And the last one.
>> Our script.
>> Our script. Helpfully, we can only run JavaScript via linking it in our C++ DOM element. Beautiful. Okay, let's actually have a little schema here. This is a reminder for ourselves so we don't lose track. Our HTML file can load in.
[00:05:56]
I will say this, as I said, hard parts the model is, it starts hard and it becomes tedious. That's what a review. But there we go. That's what ensures. We can never forget it, hopefully ever again. And that's why it's my job to be as hype as possible to help you, that's not my job, actually, it's a very tragic job, to help you keep pushing through building this mental model on repeat because I would not, what a way to spend the day.
[00:06:30]
All right, there it is. JavaScript loads from the HTML file, the DOM is going to display the actual pixels on the page via the layout and render engine. And JavaScript has a bunch of functions, no, objects by name that are full of methods that give access to all sorts of areas of the web browser, but what we're most interested in is the one that gives access to document.
[00:07:03]
So let's start running our JavaScript code. There's our memory, I Should probably start calling people.
>> Don't forget to -.
>> Yes, thank you. Alexis right there, not by writing input.
>> [LAUGH]
>> That's not how it works exactly, but instead, our layout and render engine is much cleverer than, obviously, than myself.
[00:07:26]
And there it is. It's our beautiful page. Thank you to Alexa. Now what is this document object gonna have in our memory? Talk me through it.
>> Yeah, it's exposed by the global context by the browser, and it allows you to access the document object model in JavaScript and set up links to the different.
[00:07:54]
>> From JavaScript, exactly. In C++, so from JavaScript, exactly. And exactly as you rightly say, it's gonna have access via this hidden link, technically referenced as a C++ pointer to that position in C++ memory, it's a symbol as well. It as simple as that, people. Simple as that.
[00:08:13]
And we have in it a whole bunch of methods, a slew of methods, but we're going to only use one here that I can see why, what's the one we're going to use?
>> It looks like query selector.
>> Beautiful, query selector. Absolutely, and that is perfect. A function that is going to when it gets called, go to the link, see that it's linked to this model of the webpage in C++.
[00:08:41]
Query it for whatever the given selector, whatever the given label by which we're gonna select an element is, and then return for us a link to that particular element. And that's exactly what we do right now. So I don't know, do we have space in general to do a call stack up there and a callback queue, or is it better?
[00:09:03]
This is sort of freed up space here, right, maybe we can do it. From now on I think we're going to do our call stack here. I think that's fine, it didn't do any harm, and then we have our callback queue just so that we're not running out of horizontal space.
[00:09:22]
So that's our JavaScript call stack and our callback queue. And so let's get going into our JavaScript thread of execution. Okay, we have some data being saved, we have accessor objects for div and input on the DOM. We then save two functions that our handlers, handle click on handle input, assign them to their associated DOM objects, we also save a function data to view.
[00:09:51]
This is our core function that's going to translate based on, one word we might use for it is description of the relationship between that underlying data and what the user sees such that everything the user sees that could ever be changed by them must be via a change of that data and then an execution or running of the corresponding data to view converter function.
[00:10:15]
No mysteries, no which of our ten handlers was this change what the user sees caused by. Nope, we have one place, one function that converts underlying state, underlying data, underlying content into view. It requires some kind of creative thinking in terms of how can we ensure that everything that a user sees is defined as a consequence of some changeable data in JavaScript.
[00:10:39]
But you know what that is? You know what that is? That's good reasoning, that's reasoning that I can get my head around. That's everything in the view must be a consequence of underlying data, that's not under seven different pathways through user handles. I'm perhaps implicitly changing data but I'm changing the view, no.
[00:10:58]
And everything must depend on like for like, one-to-one data in memory that generates a given view for that particular moment of data. Okay, so let's do it, people. Yeah. Ian, please.
>> Is that what one way data binding is, where the view is a function of state, it goes from the data to the view, the one way?
[00:11:20]
>> Yeah, exactly. I like to think as we're gonna see in a moment, cuz we're still gonna have to get data from the user when they type here, it comes back to JavaScript. So how is that one way? The way I think about that is it ends up being like a submission to JavaScript.
[00:11:33]
Hey, I just type the letters HE, or I just type the letters Y, or I just type the letters IAN, can you, if the handler does it, update the data in some way based off my user action? Yes, user action contains data, but the handlers determine how you're going to update the data, it not like it's gonna flow automatically.
[00:11:58]
It's a submission by the user, which we are then going to in the handler function determine how to update the data. What is guaranteed is the data to view conversion back, well, not back, but the data convert. Whatever the data is in memory, that is gonna determine what shows up here.
[00:12:14]
Now, we then have handlers that can change that data, but that's on us to then write those handles in such a way. What is fixed is the relationship from the data in that data to view function permanently says take the data here, and nothing on this display can be that has not been determined from data here in memory.
[00:12:35]
So one way is a bit of a -.
>> The view are really the one I'll take care of handling view. So we always selectively take the data from a view when we want to, and the data just always -.
>> Pass every bit of data. I like that.
[00:12:50]
>> Everything -.
>> What a nice way of putting it in.
>> Yeah, it marches, that's really nice. We will -.
>> [INAUDIBLE] whatever comes.
>> We control what comes into the data via the user's specific actions, what we don't control is everything in data will always populate to the view.
[00:13:08]
No sort of deciding which bit we're gonna update on the view. It's like you can change data from just one action from the user, there's lots and lots of different places that can change the data, but there's only one place that can then repropagate that all out. So it's like a very narrow flow back to the data specific only to the user action.
[00:13:33]
We're not re-grabbing all data back to the underlying data, so we're not grabbing the whole DOM worth of data, but just one small piece comes change comes back. But from this direction, from this ocean, all pieces will update. So it's like a very narrow and then a sort of spray back out the whole way.
[00:13:52]
Yeah, so I mean, it's always two way, cuz other is how you get the data back.
>> Yeah.
>> But the direction from the user, from the view to the data is very pinpoint, and also very custom based on every single possible action the user can take. Whereas the flow back, the one way we refer to is very broad complete, and automatic, and unspecific, it's everything.
[00:14:23]
And that means we have no reasoning to do about which bits to display. And that's because, A, we can't see it when the user sees it. B, we wanna have it as simple and predictable as possible. D, there's lots of different ways that could change and we're not really sure, whereas when the user takes an action, we can probably narrow it down to a small piece of data that needs to change.
[00:14:43]
Whereas what the user sees based off that piece of data could be 50 different things could change. So let's have all of them, we don't need to reason which ones need to change, have them all change. Absolutely, very, very thoughtful question coming from Mathew there.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops