Reactive Web Dashboards with Shiny Transcripts
Chapter: Advanced UIs
Lecture: Render express

Login or purchase this course to watch this video and the rest of the course contents.
0:00 In the last session, we learned a little bit about how to build dynamic user interfaces with Shiny by updating input elements.
0:08 So we had a little button. When you click that button, it changed something about the user interface.
0:12 But what if we want to take that one step further and actually add or remove things?
0:17 So have your whole application actually dynamically respond to the user.
0:22 One of the great things about Shiny is that it has a really robust pattern for doing that called Render Express.
0:30 So in this application here, we're going to try to build a password-authenticated dataframe. This is just a basic one.
0:36 I wouldn't use this for anything, you know, any sort of actual serious security purposes, but it's a good illustration.
0:44 So we're going to add, first of all, an input text. Oops. And we'll call that ""password,"" and the label will be ""enter password.
1:01 What we want to do here is have the user enter a password and only show the dataframe when that password is correct.
1:09 So in this case, it's going to be ""penguins. One way we might want to do that is with a conditional.
1:15 So we would say ""input password equals penguins,"" and if it does, say ""render dataframe,"" and
1:32 define our little data function that returns the dataframe.
1:37 But this is going to fail with an error, because we're trying to call this input password outside of a reactive context.
1:43 So remember, whenever you try to call input outside of a render function or a reactive
1:49 calculation or reactive effect, you're going to get this error, ""no current reactive context,
1:52 because Shiny doesn't know what to do with that call outside of a render function.
1:56 Those render functions kind of define the nodes of our reactive graph, so if we don't
2:00 have those nodes, we can't really figure out when to render things, or what, in fact, to render.
2:06 The solution to this is to use the decorator renderExpress. Decorator renderExpress is kind of a pretty generic way of a renderer, which doesn't take
2:14 a particular output, it doesn't take a plot or a table. Instead it creates some Shiny express code, which are then added to your application under
2:23 certain contexts. So we'll create another function here, and I'm going to call this ""dynamic data,"" just to separate it from the inner renderer.
2:35 And now if I run this, I'm not going to get that reactive error, because this is taking place within a reactive context.
2:43 And in fact, if I go and I type ""penguins,"" I'm going to get the data frame out.
2:48 So this is a really great pattern, and it differs—it's very different from the pattern
2:53 we used before, updating an existing element, because the data is actually not in the application when the user starts it up.
3:01 So if I open this up, I can prove this to you by using something called the Chrome developer tools by inspecting the HTML.
3:08 I promise this is the only HTML we're going to look at in this course.
3:11 And you don't need to be able to really read this super well, but just notice that there's kind of only one thing with an input ID.
3:17 So the only thing that's here that's kind of Shiny-related is basically this input password ID.
3:24 So there's nothing down here in the bottom part where the data frame is going to go.
3:28 You can sort of see over here, if we close up that div, there's a bound output called dynamic data,"" but there's no data in here.
3:35 There's nothing about the penguins dataset. And every time I make a change here, this application is going to re-render, and each
3:42 time it's going to check, ""Did he enter the password correctly? Should I render that data?
3:46 And each time it's going to say, ""No, not going to render anything,"" until I get here.
3:51 And suddenly, you see there's actually some stuff in this bound output.
3:54 You see the data frame over here, and now when you look down here, there's a Shiny data frame, and it's got a bunch of different things in there.
4:03 Once the password has been entered correctly, it's rendering this output. And you can put any type of Shiny code in a render express.
4:12 So for example, I'm going to have a little else statement down here, and I'm going to say, ""Please enter a password.
4:30 So this is going to be some code here, and when I first start it up, before I enter the
4:35 password, and the password is incorrect, I'm going to get this, ""Please enter a password prompt.
4:39 But when I actually do enter the password correctly, I'll end up with this bigger data frame. You don't necessarily have to have just one thing.
4:51 For example, I could have an input here. Let's call it ""slider. So now when I enter this, oops, missing a value.
5:14 So I can include the slider and the data frame as well. I haven't connected these two, but you could connect them in the same way that you connected
5:20 them in the previous exercises. And this kind of illustrates one of the funny things about render express.
5:26 This is a bit of a magic function, which you don't need to know too much about the magic.
5:31 But one sort of key thing here is that whenever you have a render express function, we're
5:36 kind of basically stepping into this function and reading it for, and parsing it to get the Shiny code that we then include in the application.
5:45 And as a result, it's important that render express functions don't have return values.
5:49 So you just type in the Shiny code that you want, and that's going to be printed.
5:53 So any kind of valid Shiny code that's in a part of the function that you end up in is going to be sent to the Shiny application.
6:02 So for example, if I have here, instead of ""uih1,"" I would do ""return uih1,"" I'm going to get an error.
6:09 And the error I'm going to get is very informative. It's going to tell you right away, ""Hey, don't use a return value.
6:15 Instead, it'll just render every printable line within the function body. So you don't need that. In fact, you can't use that with render express.
6:25 If you've used Shiny core or Shiny for R, this is very different from the render UI, which is the pattern in those cases.
6:32 And this is just a way of fitting this pattern into the express framework. So you don't need to think too hard about it.
6:40 Just remember that whenever you're using render express, don't use a return value. Just type the code that you want to be rendered to your application.
6:48 Render express is a lot more flexible than the update pattern that we used before, because
6:52 you can add things, remove things, include multiple things in your dynamic user interface.
6:58 And the input doesn't need to be there right when the application starts.
7:02 So it might be that only when a user enters one path of your application are you going to return a particular value. And that's the way of doing it.
7:11 So it's a powerful tool, and it's one that lets you build really flexible applications to suit pretty much any kind of user need for your application.


Talk Python's Mastodon Michael Kennedy's Mastodon