The Hard Parts of UI Development

Conditionally Updating the DOM

Will Sentance

Will Sentance

The Hard Parts of UI Development

Check out a free preview of the full The Hard Parts of UI Development course

The "Conditionally Updating the DOM" 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 walks through the refactored updateDOM function, which conditionally updates the DOM based on if the elements Array exists. The first time the function is called, the Array is undefined. The elements are mapped over and passed to the convert function before being appended to the DOM.


Transcript from the "Conditionally Updating the DOM" Lesson

>> Sweet, great, let's get to every 15 milliseconds, and in this case the first 15 milliseconds, yeah, the first time, let's get to what happens on our callback queue. Can I have, Justice, what happens on our callback queue? Yeah, don't worry, people, you're doing incredibly, we're almost there.

On our callback queue, what happens at 15 milliseconds based on our interval that we set? We've finished running that line, it's done, but at 15 milliseconds, what function is going to be added to the call stack via the callback queue, Justice?
>> Got updateDOM.
>> updateDOM, it's gonna be called callback queue for a second.

Let's put it on the call stack, and updateDOM. And we are now going to execute it. So that means, everybody, a brand new what?
>> Execution context.
>> Amazing, amazing, that is invigorating at this point, an execution context. And that execution context is executed by JavaScript. There's the pink parens as why it was saying so nicely.

And we now start executing updateDOM, and with its pink parens, we are going to create a new brand new execution context as everybody rightly said. And there it is, how big is it gonna need to be? Not nothing.
>> [LAUGH]
>> All right, not too bad, though. Into it we go and we check if elems are undefined, are they undefined or are they?

Yeah, they are not assigned at this point. So we are going to run our process of taking our JavaScript representation of our elements and hitting each of them with the convert function that's gonna create associated DOM elements in C++ and associated corresponding accessor objects in JavaScript. To allow us to ongoing, interact with the underlying DOM elements and potentially change their content in an incisive manner, not wipe them and restart.

I don't see any replaced children here anymore. Instead, we've got a findDiff that's gonna work out what actual elems' specific content to change based on when we do have our latest vDOM, the current data propagated into it. In practice, by the way, if you're looking close, and if you can hold on, we can make more changes in this.

Absolutely, we're doing a minimal diffing algorithm that can only, in this case, by the looks of it change our content but we're gonna expand it, no doubt. elems is going to be the result of hitting each element of vDOM with the convert function, it's gonna have execute convert with, so let's just do my dotted line for the map execution context.

And we go, and the first thing inside is going to be running convert on which element in our vDOM? Machick, in our first running of convert inside of vDOM, the call to map with convert passed, which index are we?
>> In input.
>> Yeah, perfect, exactly right. There it is.

Input the array.
>> Empty space.
>> No, what did I do wrong here? There it is, calling convert on exactly vDOM position index 0. New execution context, no. [LAUGH] We are not going in it because we don't have it. But we know it's there, just to be really clear to everybody, it's there.

Yeah, it's there. It's minimized. And so we're passing in vDOM numbers from 0, exactly as you said, Machick, with this string input, empty string, the handle function. And I think what is pretty cool at this point is we know exactly what it's doing. Its output is going to be, on the one hand, the creation in the C++ DOM of an input DOM element, there it is, input DOM element.

And with convert, we're also setting the value of that element to an empty string exactly and setting the handler for inputs on it, input handler-
>> To point to callback.
>> To refer to point to the handle function, exactly. There it is. And that we have as in JavaScript the output of it is an object that has a bunch of useful functions that allow us to make edits to the linked C++ element input.

And then we have a bunch of useful functions here. And that output will be added to the array that is created in map. It'll be pushed to that array. We're going to do it two more times. I'm not gonna write them out again, actually I will. Okay, there it is.

String div, string hello, and a comma and exclamation mark. And that is going to produce an element over here of-
>> Div.
>> Div, exactly div with text content of hello comma exclamation mark, nothing else. And that then also produced a corresponding object with a link and with useful functions.

And the final one from the map was for our last, yeah, the last div. And, great job, and there it is, squeeze it in. And that will also return out in JavaScript an object with useful functions and a link to a corresponding div node in our DOM with the string Great job as its text.

None of these show up quite yet. But our map call inside of it, put each of these objects into an array. And that array was returned out into, Machick, what global constant? The output of the call to map in line 14, 15 is gonna return out to what global constant?

>> Which one, just an element?
>> Elems, exactly. Exactly, spot on. Into elems, there it goes. And there we have an array with one, two, three accessor objects, each corresponding to an underlying created DOM element. And that's what we did in line 14 with our elems, it's a result of running convert on each of our current vDOM elements.

Input empty string handle div Hello!, div, Great job. And then each of those created in convert, we don't have the convert function here, we've run out of space but we remembered what it did, it created associated elements in the DOM. In practice, it'd be a super sophisticated function, can handle anything, inputs, divs, those are the two we have, [LAUGH] list elements, other things.

>> [LAUGH]
>> Yeah, and we then got our accessor objects and we put them automatically through map. Map always inside of it creates an array into which each produced output of running convert on each of the input elements is pushed into that new output array. And that is what we returned out exactly as Machick said into the global label elems.

And so in elems we have three accessor objects that we're gonna use actually from now on to make incisive, precise changes to the underlying DOM elements. I tried to squeeze them in a bit with the thought that maybe I was going to be adding new ones to replace the old ones.

Ah-ah, I'm not going to anymore, right? But we're gonna have our link on each of them to their corresponding C++ DOM element, DOM node. And they're gonna have their appropriate methods and getter setter properties, in this case we're actually just using getter setter properties on them as well.

The first one that linked to an input node has value on input and many others. The second two are divs and they have text content. We've seen that again and again, of course, there's many others, not of course, these are many others, but these are the ones we've used on repeat.

So let's do honor to them by having them here as well. There it is. And so those are each linked to, this is a big one, big line here. These are each linked to corresponding, no. That'll do, okay, corresponding, there we are. I didn't get a very good line, did I?

Corresponding, yes. What a shame. I didn't do that very well. Div, I did not do that very well. Sorry, everyone.
>> [LAUGH]
>> There we go. I didn't do that very well, did I? That's a shame, right? After such good diagramming for a bit, that is, everyone wants to have the straight lines here, not the, anyway, all right, so, but it's okay.

We now have our accessor objects for our underlying DOM elements, great. Let's get them, not even replace children here. What are we gonna do instead here, Alexa?
>> Append them.
>> Append them, exactly. Because we ain't gonna be replacing them anytime soon. We might, but we're gonna do incisive changes rather than replace as a whole.

And so we do document.body which gets us our getter for the body element to which we run our append method. And we are going to spread each of these elems, so it's elems position 0 the first argument, elems position one, second argument, elems position two, third argument. And that's going to take our link to body and append to that our linked three elems as its children.

The funny term meaning sub elements of body. And so, Alexa, help me out. What is gonna be added to our page here at this point automatically through our layout and render engine?
>> An input.
>> Absolutely.
>> And a div and another div.
>> Perfect.
>> And the input has an empty string in it, so nothing.

>> Yep.
>> And then the first div has hello space exclamation point, and then the second div has Great job.
>> Beautiful. My goodness, I think we have successfully taken our initial state, our initial data, produced a JavaScript manifestation of it. There it is. And then we have created through convert and mapping over the JavaScript implementation.

By the way, we could have sub-elements of this, we could have a full tree structure. In the challenges, if you get a chance to work on them, they're fab, you can build this out without too many changes to have it handle sub-elements, multiple layers of sub-elements as it does in full framework implementations, UI framework implementations.

And that then leads to three, our elements added to the DOM, the C++ list, and the accessor for them, and then our rendered displayed pixels on the page.

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