skip to content

Build a Custom App Dashboard

with Hirday Gupta

Retool promises to help us "build internal tools, remarkably fast". In this episode, Hirday Gupta will teach us how to build an app backend and UI quickly.

Topics

Transcript

Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON: Hello, everyone, and welcome to another episode of Learn With Jason. Today on the show, we've got Hirday Gupta. Hirday, thank you so much for joining us. How are you doing?

HIRDAY: Great, thanks. Excited to be here.

JASON: I am very excited to have you here. I'm looking forward to learning from you today. But before we get into what we're gonna be building, what we're gonna be learning, let's talk a little bit about you. For folx who aren't familiar, do you want to give us some background?

HIRDAY: Yeah, absolutely. So my name's Hirday. I'm currently a software engineer at Retool, for about a year and a half now. I've always loved building developer tools. I think, you know, ever since I started coding, which was many, many years ago now, always been like, you know, coding for certain projects or, like, something that I wanted to see in the world, and then along the way, I discovered that during the actual Dev work for that, it's hard. So what I end up doing instead is building the dev tool to make the task I was trying to accomplish in code much easier. And I didn't even realize this was a pattern until, you know, maybe a year and a half ago. I looked back on my life and I was like, holy shit, I really like building DevTools.

JASON: I mean, that's really funny because, you know, there is always the joke about those that can't do, teach, which I say lovingly about myself because I don't have the attention span to work on product. It's part of why I left IBM, to work in the dev tool space. I love working on the processes and the, like, helping people be more effective, but then when I actually go to, like, oh, we got to do that last 10% where you're fixing all the edge cases and writing all the tests. I don't want to do that part. [ Laughter ] Anyways. That's just me outing myself, 100% sure now that I will never get hired at another dev company. [ Laughter ] So, I mean, I think there's an explosion in the dev tools space right now. And, I mean, maybe that's just recency bias, but it feels to me like we're seeing more tools being built for developers than we ever had in the past. It felt like before there was, like, open source stuff, there were frameworks, there were, you know, kind of things that you could use, but a lot of it felt a little DIY or like you were using somebody else's work that they had open sourced for you. And now it feels like we're seeing actual investment. Like there are VCs in the dev tools space. There is a lot of money available. People can get full‑time jobs working on open source frameworks. Or working on tools that make developers more productive. What have you seen ‑‑ I mean, first of all, do you think that's true? And second of all, like, what do you think is contributing to that?

HIRDAY: I think that's definitively true. And I think, personally, you know, this might be a naive opinion, but I think more and more people are starting to see that, you know, the ability to write code and ship software is a superpower, and I think a lot of people, myself included, really enjoy sort of facilitating other people's superpowers.

JASON: Yeah.

HIRDAY: Including building tools to help make people far more productive. And I think that's definitely contributing to that notion. But I think, like, the other thing also is that, you know, a software engineer's time is expensive, and I think, you know, the justification is really easy to make if you're making X, Y, Z process way easier for a software engineer. It's easier for a company to justify that purchase.

JASON: Yeah. You know, and that brings up a good point, which is that, you know, if we look at ten years ago, 15 years ago, how much developers influenced the world, it wasn't the same, you know? Like you still didn't have, like, online banking existed ‑‑ and booking things online existed mostly. And ecommerce was there, but it felt like when you went to somebody's online store it was, like, sure, you can buy this here, but we'd prefer you came into our physical store, right? And it feels like over the last, I mean ‑‑ with ecommerce especially ‑‑ the pandemic just, like, final nail in that coffin. So many stores only exist online now. I feel like the majority of my shopping is done online, not because I want to necessarily buy shoes online, but because, like, the shoes that I want don't exist in stores. They're only available on ecommerce stores. So that really shifted the balance of, I don't know, the world, the Western world at least to suddenly developers are, like, the underpinning of the whole economy. Like your company is gonna rely heavily on internet presence, and that internet presence is driven very heavily by developers. So now you've got, you know, developers are the people that if you don't keep them happy, you're not gonna be able to hire the right people and your website's gonna suffer, and that means that people who are trying to use your business are gonna get frustrated with it, and they'll go to the company that's got a better online experience. Your company ceases to exist. That's a really interesting shift in power. Developers hold a lot of the weight, I guess, in companies now. Which means we can do things like demand better tools. And that's why we're seeing everybody change jobs every 18 months, is because they know that everybody needs developers desperately, and it's become the developer market. They can go wherever they want. We'll see how long that lasts. We've been looking at the markets lately. I'm holding on tightly for my job ‑‑ [ Laughter ] But the current state of things at least is that developers have a lot of influence. And making developer tools is a great way for companies to stay competitive on all fronts. On hiring. On income. On, you know, driving brand love and customer awareness. All of these things rely on developers now. And so, to me, that's sort of why the money entered the space. That's why you can suddenly get funding for a frontend framework or Fig is a command line terminal, but they got funding because it makes developers more productive. And that's incredible. So there's ‑‑ yeah, like, it's just interesting to see that we've sort of had the transfer of power go from executives. Because now if executives make their developers mad, the executives just lose all their developers and then the executive gets replaced. We're looking at companies like Microsoft where, like, you've got the new CEO comes in and, like, gets all the developers to love him again, right? Like there is this amazing transformation where Microsoft became a developer‑focused company after years of not having that reputation. And they were able to bring in a ton of stuff. They bought GitHub and all these things. And suddenly everybody's like, yeah, Microsoft is a very developer‑focused company. We would use Microsoft laptops for work. Nobody would use Microsoft laptops for work in 2010. Are you kidding me? Like it's incredible how much that has influenced the market. Anyways, I'm off on a bit of a tangent here.

HIRDAY: No, but I absolutely agree. I think, like, the trend you identified is spot‑on. More and more companies care about their online presence, which is why, you know, as people with the keys to that online presence, developers hold a lot of that power. But there is a secondary trend as well, which is that even if they don't want to be, most companies are going to be tech companies now. Whether that's, like, you know, because their customer‑facing work is technology focused or their internal processes are run on, like, you know, more and more complex technology.

JASON: Mm‑hmm.

HIRDAY: The ease of development that some of these developer tools we were talking about enabled in the ‑‑ for, like, you know, the high‑lift, customer‑focused, pixel perfect work, right? People are seeing this and saying, hey, my internal processes could have been that must faster if I had a tool that worked like that. Or a tool that I could, like, shepherd and mold into something that worked like this. We're seeing this across the board, not just from companies with user‑facing websites, but also, like, companies that sell paper in Central America or companies that, you know, build air conditioners, right? People that have no business being in the market for developers. Software developers that build customer‑focused websites. They are. And that's because they run these massive operations that, you know, will benefit from these things.

JASON: You know, you bring up something that is pretty interesting around internal tools. And I'm just thinking ‑‑ so, you know, I'm at Netlify. And Netlify is, like, by every account a developer‑focused company. It's, you know, it's engineering all the way down. And even at Netlify, we find ourselves, like, I need a dashboard for showing whatever. Our customer funnel. Oh, we need to pull this new view for, like, how this campaign worked or how that campaign worked. And all of that is data that we have, you know? We've got the telemetry and we've got, like, who clicked what email or whatever those things are, but what we don't have is a way to actually, like, use that data. Because we have a bunch of different tools, and that data sits across a bunch of those different tools and in different databases, and we need, like, an actual hardcore data scientist at this point to, like, go in and write SQL queries and make sure that the queries are useful, and then turn that into, like, data, and then we have to hand that off to a dev who can visualize it for us. Or try to put it into a tool, like Mode lawyer something that will let us write those queries and visualize those queries for us. But what it ultimately means is we're missing a lot of those dashboards because we don't have the bandwidth internally to, like, build them, right? And so even though we do have, you know ‑‑ Netlify's a company of a little over 200 people. If I had to guess, I'd say 50% of us are engineers. We still don't have enough bandwidth to build all of the things we need inside the company and still support all the things externally that our customers need. So we make trade‑offs. And typically the trade‑offs are internal. Well, we'll go without that dashboard. We'll have someone use an Excel spreadsheet instead of that. Now we've got someone doing manual stat pulls and entering into a spreadsheet. We're pretty sure the math is right, but who knows? I think every company can feel that pain a little bit. Because we've all been in a meeting with a VP who has got an Excel sheet like, where did this data come from? Is this updated? When is the last time somebody updated these numbers? Are they still correct? Companies existed without internal automated dashboards for a long time, but it's so much easier. Like there are dashboards that are automatic, and those ones we rely on a whole lot more. So this, I think, is a dovetail into the specific kind of tool you're working on. So maybe you should ‑‑ I think I just teed up a great pitch. Hirday, what is Retool?

HIRDAY: Retool is a way to build exactly those dashboards that you were just talking about with very, very little developer effort involved. I think the core of the pitch is that, you know, there are these repeated processes in software engineering and then there is the specific, you know, app‑specific, business‑specific logic that you want to write. The pitch is ‑‑

JASON: Right.

HIRDAY: You take away the boilerplate and just allow you to write the business‑specific. And I think we do that in a variety of ways, by making it easier to connect to data sources. By giving you a custom library of beautiful components that you can just drag and drop on to the canvas and connect those data sources. By giving you the ability to write queries that can write back to, you know, your Postgres database, your API, and giving you access controls and SDLC around the whole thing so it feels like a real app and it's deployed like a real app. So it's writing back to your database, so it needs to be protected, right? And, yeah, that's kind of the exact type of use case that we make very easy. And, you know, we see adoption from company like Netlify that need the, you know, dashboard that they don't have developer bandwidth for. We see adoption from companies where they haven't even had bandwidth for the first one.

JASON: Yeah.

HIRDAY: So it's the whole spectrum. And dev tools like Retool, I think, are just lowering the bar and raising the ceiling and making that, like, much, much easier for the whole spectrum of users to really come forth into, like, a digital‑first and a tech‑first world.

JASON: Lowering the bar and raising the ceiling sounds like the hook to a club anthem, by the way. [ Laughter ] So I think if you decide that you're sick of building developer tools, you've got a star‑studded future ahead of you in the club scene. [ Laughter ] So, okay, let's talk a little bit more in the abstract about Retool. Because I feel like when we talk about these tools, especially in the developer tool space, it's really hard to quantify, like, what is the impact of it. And every single dev tool start‑up that I talk to is always like, yeah, we're gonna make you more productive. We're gonna take away this thing or add this thing. The end result is that you're gonna be able to do more. And, you know, it's sometimes hard to get down to the specific value prop. So let me ask a very pointed question, which is, like, when Retool is, like, specifically what is Retool doing? Like how do I ‑‑ if I'm gonna use it, am I, like, am I using templates? Am I, like, what is the core value prop of Retool is maybe a more concise question.

HIRDAY: Yeah, the core value prop of Retool is that basically we are a ‑‑ we are a visual coding platform. And so, you know ‑‑

JASON: Oh, okay.

HIRDAY: If you were to spin up a React Native app using NPX Create React App. You'd have to spend 30 minutes reading the documentation for React Table. And then you'd have to test it. Spend a lot of time reading the docs for the API or the SQL database if you're gonna call. And then you'd have to, like, you know, either build the connecter that would have to talk to SQL or make the like fetch call and make sure you get all the parameters right. Get that data into your React Table and then start playing around with what you've built, right? We take that entire boilerplate process and make it just available to you in a UI where you can drag out a table, write, you know, put in the config for a resource, connect it, and then write out the query, and it's kind of done.

JASON: Nice, okay.

HIRDAY: Yeah.

JASON: So to say that another way, there is a bunch of boilerplate involved in just, like, the plumbing that gets data working. Like if I've got a database over here, there's the code that I would need to write to connect to that database and, like, pull in data. On top of the query. Like knowing what data I want. And then there's additional plumbing that I would need to do to make that data into a format that I can display in a table. And so that code is code that I have to write. Then there is additional code that I would need to write to, like, build the table itself. Maybe I use a component for that, but then I have a little layer of, like, middle ware where I have the API response and I have to write middle ware to massage that API response into the table. Then there is the work to actually put it on the screen. Even if I'm using components, I've still got to build the page and stick the components in there and do a little bit of code to make it look kind of nice and, you know, make it legible, really, right? So what you're saying is that Retool is handling all that plumbing so I'm saying use this database with these credentials and I want to put it in a table.

HIRDAY: That's right. That's the lowering the bar part. We have the raise the ceiling part. Server‑side pagination. It would take days to build that from scratch on your React Table, right? So that's just one example of raising the ceiling. Because we have this end‑to‑end control of our editor and the editing environment we are in, we can start to provide these features for you, you know, not even beginning to talk about authentication, for example.

JASON: Sure.

HIRDAY: Right? Which is another out of the box feature for us. Yeah.

JASON: Great. Okay. All right. So then I think we are ‑‑ let's see, do I have any other abstract questions? Chat, do you have any other abstract questions? I see a couple folx in here. Let's see, Eco just subscribed, Cynthia subscribed, Michael subscribed. Thank you all very much for subbing, I appreciate that. Michael's at ten months, that's amazing. Six months for Cynthia. Over 22ants for Eco. I'm not seeing any questions come in from the chat. So here's what I'm gonna do. I'm gonna take us over into pair programming mode and we're gonna start actually trying something out. So here we go. Now ‑‑ got the inception going. So we'll move this over. All right. So we are talking to Hirday today. So make sure you go and give him a follow on the old interwebs. And this episode, like every episode, is being live captioned. You can get those live captions on the homepage of learnwithjason.dev. We've got Jordan with us here today from White Coat Captioning. Thank you, Jordan, very much. That is made possible through the support of our sponsors. We've got Netlify, Nx, and Backlight, all kicking in to make this show more accessible, which I appreciate very, very, very much. And we're talking about Retool. So let's drop the Retool page in here. So typically what I would do is I would be looking at my terminal here. But it sounds like that's not how we do it at Retool. We're not getting into a new project in the terminal. We're doing something different. So how do I get started if I want to get started with Retool?

HIRDAY: Why don't you just click "try for free up there."

JASON: Try for free.

HIRDAY: And we'll sign you up for a cloud account.

JASON: I'm going to sign up with Google to save us some time.

HIRDAY: Sure.

JASON: How familiar am I with JavaScript? Oh, no, this is where I have to, like, see, am I gonna be ‑‑ am I gonna be modest in front of the chat. No, I know JavaScript. [ Laughter ] Let's see. So, yeah, LWJ. We can make that work. Allow people within my team ‑‑ that kind of doesn't matter because I'm the only person on my domain, but roll it anyways. Oh, SSO enabled out of the box, though. That's dope. That's really cool. Okay. All right. Now I don't know what happens after this. So I'm just looking at a list of databases.

HIRDAY: Cool. So this is our, you know, sign‑up, like, you know, once you've just signed up, if you have a use case screen. So, Jason, we're gonna be building ‑‑ what are we building today?

JASON: I don't know, you tell me. [ Laughter ]

HIRDAY: I had a few app ideas in mind. One of them was a Twitter swear jar. [ Laughter ]

JASON: Good.

HIRDAY: Yeah, so I was thinking that we could build an app that talks to the Twitter API, gets us a list of tweets, and then we can start flagging them for certain curse words and start charging, you know, charging ourselves and keeping ourselves in check, if we start cursing too much on our Twitter. [ Laughter ]

JASON: I love it. I love it. This is good. So, yeah, let's do it. So in an effort to make sure that we don't have to add a bunch of, like, editing all over this episode, to keep it PG‑13, I think instead of actual swear words, we should come up with, like, almost swear words. Like if somebody says, like, dag nabbit. Or if you say butts, that will go in the swear jar. Chat, PG‑13, what are our almost ‑‑ fudge, that's a good one. More. Fiddle sticks. Love it. Okay, chat, you keep doing that, and we're gonna put together a query to do this. So as I'm scrolling through, I see a bunch of data sources. I don't see Twitter in here directly, though.

HIRDAY: Yep. So, you know, we support, you know, if you don't see the resource and it has a REST API, we can use the generic REST API source. I'm gonna have to pull up Twitter's documentation to guide you through this. Maybe you can pull it up as well.

JASON: Okay. So we're gonna get the Twitter API.

HIRDAY: Yep. And then ‑‑

JASON: And that's gonna put me here.

HIRDAY: Actually signed up for the API a while ago. So I can ‑‑ yeah. We can get some keys.

JASON: Okay.

HIRDAY: Yeah. If you go to the ‑‑ I don't know, any document ‑‑ yeah, make your first request. Sure. You'll see the actual URL for the endpoint somewhere in here. I think that's what we need. Yeah, perfect.

JASON: Okay. And now I just need this part, right?

HIRDAY: Mm‑hmm.

JASON: And then will point me to something else. I got my base URL.

HIRDAY: Perfect. Why don't by save that for now, and then we can see what goes on.

JASON: Okay. Do I need to do the auth?

HIRDAY: We'll start with this and then we'll get to the auth.

JASON: Skip the tutorial.

HIRDAY: You've got live help.

JASON: You, chat, don't ever skip those tutorials. They're very helpful. Me, I do whatever I want. [ Laughter ]

HIRDAY: Cool. So we're currently in our onboarding page app, which you can rename if you want to, you know, whatever you want to rename it to. But, yeah. So, you know, why don't we ‑‑ so why don't we get started with, like, maybe just, like, a look‑up for, you know, a user on Twitter.

JASON: Okay.

HIRDAY: That might be, like, a good place to start.

JASON: So users by username. That's an easy one. It would literally have that one open right now. So I'm going to get this. And we're gonna do this. I'm gonna do that. And we'll just ‑‑

HIRDAY: Yep.

JASON: Okay. So if I want to do that ‑‑

HIRDAY: Yeah.

JASON: Preview.

HIRDAY: Yeah. Oh.

JASON: Preview only. Unauthorized.

HIRDAY: Unauthorized, right. So let's look up ‑‑ let's look up the Twitter instructions on authentication. Because I think it's fairly complicated.

JASON: I mean, this is definitely a good one to, like ‑‑ okay, you have to now deal with ‑‑ let's see. You have collected your API key in secret. User access token in secret. App access token. And then getting access to the Twitter API. Getting access. That's gonna be auth. Apps key and token. Now, you already have these, right?

HIRDAY: Yeah, so I have a key and a secret, which ‑‑

JASON: Okay.

HIRDAY: I'll be securely transmitting to you. So, yeah, then I think we can generate ‑‑ let's read these here.

JASON: Yes. Generate user access tokens or app access tokens. My guess is we want an app access token?

HIRDAY: Yeah, I think an app access token sounds right to me as well.

JASON: Okay. So I'm gonna click through to app access token. App only. That's probably right. We don't need to make a request on behalf of the user. Okay, so I'm jumping through here.

HIRDAY: Perfect.

JASON: All right.

HIRDAY: You would need a bearer token.

JASON: All right. Here's our bearer token. I love OAuth. It's such a load of mental gymnastics. Okay, hold on. Then you do it and you're like, oh, so I just get this token? [ Laughter ]

HIRDAY: Yeah, it's the classic all this effort for no reward kind of ‑‑

JASON: Okay. So, HTTP post to OAuth2/token.

HIRDAY: It sounds like this is a request we want to make basically prior to every request or prior to a certain set of requests. And then we're gonna need to get this token and use it in every request we make.

JASON: Okay. Yeah.

HIRDAY: So we actually, you know, we've dealt with this pattern before at Retool. So we have a feature in our resources just for that. So if you go back to ‑‑ so if you go the homepage here ‑‑ it'll be the retool menu on the left.

JASON: Back to home.

HIRDAY: Yep. Uh‑oh, we'll get you off that free trial, Jason, if you'd like. But we're gonna go to the resources page here.

JASON: Resources, here.

HIRDAY: Mm‑hmm. And open up the Twitter API. Cool. So if you scroll down here, all the way down, you'll see authentication as an option. And so these are all the auths we support kind of out of the box.

JASON: Oh, so we want OAuth 2?

HIRDAY: No. The only reason I know this is because, like, I was heavily involved in, like, the development of these OAuth features. The reason we don't want it is Twitter doesn't follow the standard OAuth2 spec.

JASON: Custom auth.

HIRDAY: And what we want is an API request, right? So what was that post‑URL?

JASON: Post. And then we need to send it to here.

HIRDAY: I see. Do we need any additional perams on that?

JASON: Probably. I need to send an authorization header. Our base 64 encoded ‑‑

HIRDAY: What is step one.

JASON: So we take consumer key. Consumer secret.

HIRDAY: Ah, okay. I think I know what this is.

JASON: So these are already encoded.

HIRDAY: Mm‑hmm.

JASON: Bearer token credentials is the key and secret separated by a colon.

HIRDAY: Yep.

JASON: And then we base 64 encode that.

HIRDAY: The whole thing. Okay, cool. So just so you're not sharing your screen with that, I'll do the base 64 encoding and share you the encoded key.

JASON: Okay. I will set up the headers. So it's going to be authorization. We're going to put in a string there. And then I need to put in the content type. Do I need to send all this? Or can I just send authorization? Must include a content type of application.

HIRDAY: Throw that in the headers. It looks like there is a body as well.

JASON: Okay. So let me add a content type. And then we've got grant type ‑‑ okay. So we're going back here. We're going to body. And the body type is going to be form encoded.

HIRDAY: Perfect.

JASON: Okay. All right.

HIRDAY: I shot you over that value, if you want to grab it from ‑‑

JASON: Got it. So I'm gonna pull this off screen so that I can put this value in. There's my authorization. And when I go out, it's ‑‑ oh, it's almost hidden. Okay. So I'm just not gonna bring that back on screen.

HIRDAY: Yeah, if you can scroll sort of lower than that, we might need to bring that screen back, actually. So if you want to delete it, you can delete it.

JASON: I'm below ‑‑ the authorization header is up there with the value filled in.

HIRDAY: Security by authentication. [ Laughter ]

JASON: Security.

HIRDAY: So let's add a new step. So basically, you know, this is going to give us back that value, right?

JASON: Yes, okay. So we get our value back. Example response. Token type. Bearer access token is here.

HIRDAY: Yep.

JASON: So, verify, validate, and then authenticate. So then we would just be able to send that token in. Okay. So that means that here we need to, like, get the value out. Right?

HIRDAY: Yep. That's right. We define a value. And then you can call it whatever you want.

JASON: Okay. Value variable and then ‑‑ ooh, this is cool. So I get HTTP 1, which is this first request here, right?

HIRDAY: Yep, that's the first request.

JASON: And then it was response.

HIRDAY: What was the ‑‑ just token type in there? Okay.

JASON: There is token type and then access token. So I want response.accessToken.

HIRDAY: If you scroll a little further up, you'll see the prompt is prompting you to use HTTP 1.body instead of response.

JASON: Body.

HIRDAY: Perfect. And then I think if you save these changes, you should be able to test the auth workflow.

JASON: Okay. Is this going to show the variable?

HIRDAY: It's going to show the bearer token, but that's fine. You can run auth tests again and then the bearer token gets invalidated.

JASON: Invalid request. Missing required parameter, client secret. What?

HIRDAY: We put that in, I thought, right?

JASON: We put that in. Give me a quick second to get this up in the right place.

HIRDAY: Sometimes when documentation say "body params," they can also mean URL params.

JASON: All right. We're looking at in our request, example request, authorization header. I have spelled authorization correctly. Basic is the encoded ‑‑ is this supposed to be there.

HIRDAY: No, no, no. Definitely not.

JASON: Yeah, that would be weird. And then we've got our content type.

HIRDAY: I think it said something about client credentials, right?

JASON: It said something about the client credentials, but I added those. Body query, content type. Post‑content type. Can I just make my body, like, raw? Raw. And then I'm gonna put in this instead.

HIRDAY: Yeah, because it's, like, form URL encoded, let's just also just try putting it in the URL params instead.

JASON: Missing required parameter, client secret. It, like, wants the client secret, though. OAuth2 token. Maybe it's ‑‑ [inaudible] let me try again. Hold please. Successfully authed.

HIRDAY: Nice.

JASON: All right. So here was the problem. Let me try to get to the right place so this isn't giving away all the secrets. Here's the problem. I included /2, but there's no /2 on it. So let me get back down for a second to what it showed us. I won't show the token, but I'll show the rest of the response. So we get this gopes. A debug state. Current user. All those good things. If I keep scrolling down, down here, the body includes the token, but I just won't show that.

HIRDAY: Cool.

JASON: So we're in. We're connected. It's working.

HIRDAY: Nice. Let's scroll all the way back to the top then here. Because I think what we want to do is include this variable as a header in every request, right?

JASON: Okay.

HIRDAY: So let's go to headers in this section of the editor, right, and add authorization. And then how did that ‑‑ how did that want us to put it in, the documentation? Was it bearer and then the value?

JASON: Yeah, so it would be ‑‑

HIRDAY: Yeah, so here is me saving you about ten minutes of reading the Retool docs. There is actually no cullies for this one. For variables defined in the custom auth, it's ‑‑

JASON: Recall this Twitter bearer token, right?

HIRDAY: Mm‑hmm.

JASON: Okay. Good. Happy?

HIRDAY: We should be good to try this ‑‑ try that same request we were make out again. Did we save this?

JASON: I certainly hope so.

HIRDAY: I hope so, too.

JASON: I guess we'll find out momentarily. So when I go ‑‑ what do I do first?

HIRDAY: We can create a new app. Yeah.

JASON: Okay. And we're gonna call this Twitter Swear Jar. Create. All right. And now we're gonna in. We've got the ‑‑

HIRDAY: Yep.

JASON: ‑‑ setup here. I want to go back to where I was on the ‑‑

HIRDAY: One more back?

JASON: Is this where I need to go? Make your first request. And then if I go down here somewhere, there was that ‑‑ here it is.

HIRDAY: Right there.

JASON: So I want this one. And that's here. Here. Okay. Review. Unauthorized.

HIRDAY: Jason, for me, the bottom part of your screen is actually cut off.

JASON: Let me make sure ‑‑ there we go. That should put it in view. And I've got to scroll down here. So I'm getting unauthorized.

HIRDAY: We may not have saved.

JASON: Damn it! Okay, hold on one second. This is ‑‑ all right. So I'm going to ‑‑

HIRDAY: I'm not sure if the window is actually a little bit smaller than usual, but the right‑hand side panel is actually ‑‑ yeah, there we go. Perfect.

JASON: Okay. Maximize query editor. I'm going to just save it. And it's gonna fail. But that's okay. But I'm gonna go back to resources. And I'm gonna go into my Twitter API, and we didn't save the thing. Dang! Authorization. And it was Twitter bearer token.

HIRDAY: With a bearer on it.

JASON: Yes, it was. All right. You are saving me a bunch of time here. All right. Let me slam back down to the bottom here and we're going to test auth workflow again.

HIRDAY: Perfect.

JASON: That part is working. We're going to go back to apps.

HIRDAY: I think it was already in the other tab already.

JASON: Oh, it's already in the other tab. We're gonna preview. No. And the reason no ‑‑

HIRDAY: You might need to refresh this page.

JASON: Refresh.

HIRDAY: And hit run. Oh, no, that's not good.

JASON: Okay. So here's our API request. Init. Headers. Authorization is sanitized, but I'm doing something wrong. Users by username. Let's just double check one more time here.

HIRDAY: Mm‑hmm.

JASON: API. Twitter.com/2. Users by username and then username, okay. You but in your bearer access token.

HIRDAY: Mm‑hmm.

JASON: Yes, authorization, bearer access token. And you should get back a thing. But the thing that we have is not the thing that we want.

HIRDAY: There is a suggestion in the chat. Do we need the dollar in the front?

JASON: That's a good question. Do we need the dollar in the front?

HIRDAY: What is the dollar?

JASON: Like in ‑‑

HIRDAY: Oh, the dollar username? Oh, no, no, no, I don't think we need the dollar username.

JASON: Not the dollar username, but this one. Is it like a batch ‑‑ no

HIRDAY: No, that is not. Let's check our spellings everywhere.

JASON: Yes. I'm gonna take Twitter bearer token, and I'm going to ‑‑ I'm actually going to pull this off screen so I don't accidentally show this token. And we're coming down to here, where now we're past it. So I can bring it back. All right. So we've got Twitter bearer token. And that should be HTTP1 body access token.

HIRDAY: Yep.

JASON: Is there a way for me to validate this? Like when I test the auth workflow?

HIRDAY: Yeah, when you test it, it will tell you HTTP1 body access token and that should be kind of correct.

JASON: Okay. So let me save, let me test, and I'm gonna pull it off screen and just double check here. We've got HTTP1 body access token. And that is, in fact, an access token. It does not say "bearer" on it. Let me try ‑‑ let me try something just to make sure this is, like, doing what we expect it to do. I'm gonna go and try to run this query directly with the authorization header. So I'm gonna go ‑‑ what's an easy way to do this? Should I just ‑‑ I guess I could just curl it, like it says to do, right?

HIRDAY: Right.

JASON: So let me grab the docs, and let's copy this curl.

HIRDAY: ‑‑ from what Retool tells you.

JASON: Yes. So here is my username. And then I'm gonna come back here and I'm going to run this part off‑screen with the bearer token from here. Okay. So that works. Although it's arguing with me. So that's giving me the data. Which means that I have done something wrong inside of Retool.

HIRDAY: Oh, no.

JASON: Most likely, I am not configuring this thing to read properly. I don't have to go into HTTP1?

HIRDAY: Probably not. So hold on. So we defined the variable, and then we're using it here. You know, another option for now is to just manual copy/paste that bearer token you just got. Just copy/paste it into the authorization header, and that should work for the duration of now.

JASON: Okay.

HIRDAY: Yeah. Consider going to the custom auth step.

JASON: Okay. So I'm going back up. I'm going to throw this in. Save the changes. We're gonna come back out here, refresh the page. And then I'm going to preview.

HIRDAY: Nice.

JASON: And we get a response. So I did something wrong with the way that we're doing the variables, but that's okay. We can solve that problem.

HIRDAY: Yes. Cool. Okay. We're in business. So, you know, we can ‑‑ so as you can see, with these queries, right, we can ‑‑ so now that ‑‑ let's maybe build a text box that can take in a random user's name and then have that text box be in this query.

JASON: Yes. Okay.

HIRDAY: So if we shorten the query editor a little bit, you'll see the actual Retool editor. Yep, perfect. And let's bring the text box component out from the text input component. So that's a text display. Let's bring in ‑‑

JASON: Oh. Text input. Aha!

HIRDAY: Perfect. Nice.

JASON: Okay. So my ‑‑

HIRDAY: And then ‑‑

JASON: ‑‑ text input has a label. For the username.

HIRDAY: Mm‑hmm.

JASON: And that should be good, right? We can start that.

HIRDAY: If you scroll down, maybe I can show off a little bit here. So if you scroll down on the editor, you'll see the prefix icon. You can make that a little search icon.

JASON: Prefix icon.

HIRDAY: Yep, perfect. You can just search by, like, search, yep. Perfect.

JASON: Search. Great. Okay.

HIRDAY: Cool, yeah. And then ‑‑

JASON: Good?

HIRDAY: So what we want to do now is we want to, like, search by this input, right? And so if you go into the query and type your first double curlies, you will be able to put [inaudible] value in there.

JASON: Got it.

HIRDAY: Queries interact with the data from the UI. It's gonna be empty, but if you fill in the Twitter username in that text box, you will see something cool.

JASON: Okay. So do I need to save first?

HIRDAY: Yeah, I don't think it matters either way.

JASON: Okay. So I'm gonna save. And then we'll put in ‑‑

HIRDAY: Perfect.

JASON: And now we get ‑‑

HIRDAY: There we go.

JASON: There we go. Very cool. Very cool.

HIRDAY: Yeah. Cool. So, you know, let's list ‑‑ let's start by listing awe all of the tweets in the last, I don't know, I haven't really done it in a while, so maybe don't use my account, but the last three months for a given Twitter handle.

JASON: Okay. Do you know that by the ‑‑ off the top of your head? The endpoint?

HIRDAY: Yeah, I think I had it pulled up here. Okay. It's a big one. So it's going to be ‑‑ so let's start a new query here.

JASON: New query? Here we go. New query. New resource query? Yes? Okay. And I'm going to be ‑‑ yep. Twitter API.

HIRDAY: Perfect. Yeah. And we can actually refer to results of pretty much anything on the screen that you see. So from the text field to the results of the previous queries as well. And so, you know, basically, here we needed the Twitter user ID, and we couldn't just do it with a username.

JASON: Oh, I understand. Okay.

HIRDAY: So we'll do ‑‑ I think it's user/userID/tweets.

JASON: Query 1 data ‑‑

HIRDAY: So it's going to be .data, .data. And then /tweets. I think if you save and run, you would get my tweets.

JASON: Okay. So we save and run. Permanent redirect. I think I did something wrong. Do I need no trailing?

HIRDAY: Yep. I think no trailing. There we go.

JASON: Okay. So we can save and run.

HIRDAY: Nice.

JASON: And then if we go up here, do one of these. There we go. That's the tweet I sent earlier about us going live.

HIRDAY: Yeah, awesome. Cool. So now we've got a list of tweets. Jason, how creative do we want to get with this UI?

JASON: I mean, I don't know how any of this stuff works, so I'm ready to get real weird.

HIRDAY: All right. Let's, you know, what do we ‑‑ so I was imagining, like, you know, you search by the username. Maybe we have, like, a date picker so you can set the dates correctly, you know, for whatever range you want, and then just a list of tweets.

JASON: Okay.

HIRDAY: Yeah. That's probably, like, where I'd start. Then we can, like, do some analysis on those tweets and show some stats on how many swear words you're using. [ Laughter ]

JASON: Okay. All right.

HIRDAY: So, for the list, we have something called a list container. We actually have, like, components. As you just saw with the text input, one‑off input, drag it once on the screen and that's kind of all it does. We also have components that support iteration. And so if you go to list container ‑‑ maybe it's an easier thing to do if you just search, but if you want to go through the list of components we have as well.

JASON: No, I was like, oh, this is ‑‑ so let's go to list of containers.

HIRDAY: List view, I think, is what we want.

JASON: List view? Okay. So we'll get one of these and stick it ‑‑ oh, where did I go?

HIRDAY: In the header.

JASON: I'm definitely struggling a little bit with the ‑‑ I have a smaller screen size because of making things legible. So this is a little cramped. But we're gonna make it work. Oh, wait, can I hide this? Get out of here! So we'll deal with queries later.

HIRDAY: We have an idea in the chat for the last 12 cheats in a pie part, the more curse words, the bigger the slice, I think is what the chat is suggesting.

JASON: Oh, like the more likes.

HIRDAY: Oh, the more likes? I see. I see. That also makes sense.

JASON: Okay. So I've got my list container.

HIRDAY: Yeah.

JASON: And then we can put ‑‑

HIRDAY: So we can put individual components that will repeat in the list container. So maybe, like, you know, for the tweet, I was thinking we could display the tweet text, the time it was published and then just a warning label for whether it contains a swear word or not. Just as a starting point.

JASON: Okay. So text like this?

HIRDAY: Yeah. I think it might be better ‑‑ it might be easier if we ‑‑ instead of, like, putting in just the one component, we would put in a container inside the list view, and then in that container, we can put in, like, everything that is in our tweets. That container is a unit for our tweet. Kind of like we do in React with the dives.

JASON: I gotcha. The container. The container title is going to be ‑‑

HIRDAY: We can actually get rid of the title. I don't think the title looks very good on the tweet. If you scroll down, there is a hide title option as well. Or show header or something.

JASON: Layout. Alignment. Contents.

HIRDAY: You're in the title container text box, actually. So if you click on the container.

JASON: Container.

HIRDAY: Show header.

JASON: Show header. There we go. All right.

HIRDAY: Cool. And then, you know, we can drag in ‑‑ yeah, drag in the text box into that.

JASON: Okay. And then inside the text box, we want a ‑‑ let's go with ‑‑ it was query 2 data.

HIRDAY: So you can actually rename your query so it makes more sense, too.

JASON: Oh, I would love to do that, in fact. Yeah, let's rename these queries. So we will ‑‑

HIRDAY: So none of that. Just, yeah ‑‑

JASON: Here?

HIRDAY: Yeah, perfect.

JASON: Okay. So we go ‑‑

HIRDAY: Username, I guess?

JASON: Twitter user. Right? Okay. This is gonna get weird. And then I go to my query 2. And this one is gonna be tweets. Okay, this is gonna make me twitch. I got to fix that. We've got our Twitter user and our Twitter tweets. This was smart enough to update, I hope. It was. Then if I come back over here and go to this, and I've got my text input, I can do a Twitter user.data.data.username.

HIRDAY: Yep that's who tweeted. Correct.

JASON: Okay. And then we can add, like, another one in here.

HIRDAY: Mm‑hmm.

JASON: Let's put it down like this. And then we'll say ‑‑

HIRDAY: You'll also notice the field supports full markdown, so you can format it as you like.

JASON: Yeah. Okay, here is a question. I need to loop.

HIRDAY: Yep, that's right. So I'm going to save you some more time of reading the Retool docs here. You can say data.data ‑‑ sorry, "off," as in if the square brackets. And then when you say I there, it's actually going to populate using the index of the list view you are in.

JASON: Okay. So it doesn't like the text for now.

HIRDAY: Perfect.

JASON: And then I do one of these. And then it does the thing. If I go back up here, I can make this full because it's markdown.

HIRDAY: Yep.

JASON: That makes sense. And then I can drag this out.

HIRDAY: Yep.

JASON: Okay. And then we can do ‑‑ we need the, like, did swear thing. So I'll probably start with just one of these.

HIRDAY: We can have a little alert there, actually, which might be ‑‑

JASON: Oh, an actual alert. Okay.

HIRDAY: It's not an alert pop‑up. It's a little fun alert component.

JASON: Okay.

HIRDAY: So just search "alert." Yeah, right there. It's just a text box, but it has a little bit more character.

JASON: Yeah, I like it. I like it. Okay.

HIRDAY: Yeah. ‑‑

JASON: And then say something like ‑‑ I don't want the actual alert. I just want the word "alert." There we go.

HIRDAY: You cursed here.

JASON: Twitter user data.data.username. Oh, I've got an extra bracket. There we go.

HIRDAY: And then I think you can ‑‑ you can change that from an alert ‑‑ from an info alert, you can probably change it to warning language, which will be relatively funny.

JASON: Change it to a warning. Nice.

HIRDAY: Cool. We'll deal with the ‑‑ we can conditionally render that based on the swear. We'll probably do that once we, you know, have some notion of the swear.

JASON: Gotcha. All right. So let's figure out how we want to make this work.

HIRDAY: Let's take a second, though, to reflect on what we just did. Because we just designed this UI entirely in a drag and drop manner and kind of, like, you know, there are certain things that visual coding is very good at. And there's certain things that, you know, you need ‑‑ you absolutely need code for. And I think, you know, layout is one of those things where it's just amazing to just, like, drag things around the screen and CNN have them be exactly where you want them to be. And I think, like, you know, we try to provide that, like, right level of abstraction on the interface here. Where you can drop down in the code where you need to.

JASON: Yeah. Well, like, just look at how quickly I'm able to explore, too. Like you can ‑‑ I can see how I would talk myself into not building certain types of dashboards because I don't have time to, like, go in and edit them.

HIRDAY: Mm‑hmm.

JASON: But with this, I can just throw it together and say, okay, I want to be able to very quickly put together a, like, a quick view of what people are talking about. Like, you know, when did people talk about X thing? Or how often is somebody mentioning this thing? And so ‑‑ but that does involve the next step here, which is actually figuring out how we can do a little bit of logic on this.

HIRDAY: Yep.

JASON: But even just this is great. Like I can see a dashboard that I would build already with something that's, like, okay, I just need to pull activity down. What's happened? But now I want to do some logic on that activity.

HIRDAY: Yeah, perfect. Just before that, though, I think one thing we would want to do here is go to the list container. The actual ‑‑ yeah, list view.

JASON: Okay.

HIRDAY: And then let's scroll down. So, yeah, before we change the number of rows, I discovered this fairly recently. So, yeah, let's set the height to fixed. The height of the list view. That way the overflow becomes scrollable.

JASON: Oh, okay.

HIRDAY: Otherwise ‑‑ because the Retool app is infinitely scrollable, you can make it as long as you want.

JASON: Oh, look at it go. Okay. All right. I'm going to set to to 20 ‑‑

HIRDAY: So actually you can set that to a dynamic number as well. So let's put the double curlies in there.

JASON: Okay.

HIRDAY: And then say, you know, tweets.data.data.length. Great. Yes. Perfect. So now you have all the tweets in there. Or all the tweet ‑‑

JASON: All the tweets on the first page at least.

HIRDAY: Yeah.

JASON: All right.

HIRDAY: Perfect.

JASON: This is very cool. Okay. All right. Yeah.

HIRDAY: Sweet. Well, cool. Let's ‑‑ what would we like to do next? We can do some logic on the swear words. We can do ‑‑ we can add a date field. So we can, like, filter the tweets by date. That's kind of, like, two options I had in mind.

JASON: Date field, yeah. Okay. I'm gonna go in here. And we're gonna go to date. Date range?

HIRDAY: Probably, right?

JASON: Okay.

HIRDAY: Perfect.

JASON: All right. So I'm sticking the date range in here. We'll do something like that. And then we'll say start date, end date. By default, we leave them blank or?

HIRDAY: Let's default them to today and a year ago from today. Or six months ago from today. Whatever.

JASON: Okay.

HIRDAY: So, you know, again, our docs have this, but I'll tell you off the bat, we support Moment within the probabilities.

JASON: Moment.now?

HIRDAY: I think just moment open bracket, closed bracket works as well.

JASON: Okay. With this one we want moment.set ‑‑

HIRDAY: What I like to do is say subtract. So moment, bracket open, bracket closed, dot subtract, and then the object, dot subtract. I would say 6, comma, months. Perfect. Nice. So we have that date range set up. Let's use it in the query maybe.

JASON: Okay. Do we need a different format for Twitter? Because I don't actually know how it works.

HIRDAY: Should be good.

JASON: Okay. So I'm going back to my query. Under tweets. And I want to set a range.

HIRDAY: Mm‑hmm. So, yeah, we need the API fields for that. Let me just pull it up really quickly on my end. The API fields are start time and end time.

JASON: Start time and end time? Now are these URL parameters?

HIRDAY: They are. Because this is a get request. They are URL parameters.

JASON: Like that? Start time. End time.

HIRDAY: Yep.

JASON: And I want date range ‑‑

HIRDAY: Mm‑hmm.

JASON: Of value.start.

HIRDAY: Yep.

JASON: And date range.value.end.

HIRDAY: Perfect.

JASON: Okay.

HIRDAY: Let's see if you like that format. Errors.

JASON: No.

HIRDAY: Did not like that format.

JASON: It wants ‑‑ start time is not a valid RFC3339 date time.

HIRDAY: I think if you just did, like, moment, like, if you just initialize moment with the value in the .start, I think it would give out an RFC3339.

JASON: But that was it, wasn't it?

HIRDAY: That looks correct, yeah.

JASON: Oh, no, this is the minus ‑‑

HIRDAY: The time zone.

JASON: All right. So we need to go back over here. And we're doing a .‑‑

HIRDAY: Oh, well maybe not there, actually. We'll do it in the query editor itself.

JASON: In the query editor, okay.

HIRDAY: So we can initialize moment with this value. You can just pass the .start to moment. Yep. There we go. And then you can say ‑‑

JASON: There it is. I see it. I see it.

HIRDAY: Nice.

JASON: Let's try that again.

HIRDAY: Nice.

JASON: There we go. Save and run.

HIRDAY: Looks like they also have, like, a max results field and an exclude field. We can exclude retweets, in case we don't want to punish you for retweeting a sweary opinion.

JASON: Gotcha. So let's exclude ‑‑

HIRDAY: Retweets ‑‑ sorry, it's just exclude, and then the value is retweets.

JASON: Retweets. And then the max results was max results like this?

HIRDAY: We can set it to whatever we want? I would say maybe 100 or something.

JASON: 100 seems reasonable. So let's preview. Actually, that's not gonna matter. So I'm just gonna save and run.

HIRDAY: Perfect.

JASON: And then close this down.

HIRDAY: Perfect.

JASON: And we get a lot more tweets.

HIRDAY: Yeah.

JASON: And none of the retweets. So we can see that it's just my own nonsense.

HIRDAY: That's right. Cool. So for the swear words, I was thinking we could use ‑‑ we could use the, you know, good place swear words. You know, forking or, you know, all of those types.

JASON: Holy forking shirt balls. I think the good place swear words would be fun. For anyone who is nod familiar with The Good Place, this show is wonderful and you should watch it. Let's see the actual ‑‑ watch The Good Place. There. That's the actual, like, show. Watch that show. It's a good show. We are going to ‑‑ yeah ‑‑ so let's set up some filters. We want to catch ‑‑ I want to catch tweets that have some of The Good Place stuff. So how would one ‑‑

HIRDAY: Yeah.

JASON: ‑‑ do that.

HIRDAY: So this sounds ‑‑ we did all the boilerplate. This sounds like a business‑specific use case, right? We want to do something very specific to our use case. And so we allow you to just drop down into code whenever you want. So if you open up the queries, you can create what's called a JavaScript query. And that's just literally, you know, a text field where you can write JavaScript. So we're gonna write some JavaScript.

JASON: Okay.

HIRDAY: Yeah. And filter tweets, process tweets, whatever.

JASON: Okay. So we'll do ‑‑ okay. And then we're gonna run some JavaScript.

HIRDAY: Yep. And so this is the exact same run time as any other of the double curlies. So you can access anything from, you know, the query responses to what's on the screen right now. You know, it doesn't matter.

JASON: So I can do something like tweets = ‑‑

HIRDAY: You don't even need the double curlies inside JavaScript.

JASON: Okay. Then I have a problem. So we'll go with filter. And we'll go with tweets.data.data. All right. And then I'll have my things and then I can do something like ‑‑

HIRDAY: Yeah, so ‑‑

JASON: We'll just map this. So this is actually the wrong ‑‑

HIRDAY: That's what I was thinking, too.

JASON: And then in here, we can go with tweet. And inside of it, we can say, like, if tweet text ‑‑

HIRDAY: I believe, yeah.

JASON: ‑‑ includes. And we'll put in ‑‑

HIRDAY: I can't believe you hesitated at the beginning of that ‑‑ with the Retool question, how familiar are you with JavaScript? You're very familiar with JavaScript. [ Laughter ]

JASON: Let's see, can we just do, like, a very, very, very, very bad RegX here. I'm going to do like fork, shirt, and ash. Because those are the ‑‑ those are our general Good Place swears. So if it includes that, then we will tweet.swears = true.

HIRDAY: Ah, nice.

JASON: Right? Something like that. And then ‑‑ I guess we need to return ‑‑

HIRDAY: Yeah, return the tweet. Yep.

JASON: And then do we return process or are we just setting a variable?

HIRDAY: No, no, no, you can return process from here.

JASON: So we're in like a little closure here?

HIRDAY: That's right. Yeah. And then if you hit "save" here ‑‑

JASON: I'm gonna just very quickly ‑‑ string that includes must not be a regular expression. I thought includes could ‑‑

HIRDAY: Return a string.

JASON: Query run successfully. Tension. Do any of these swear?

HIRDAY: Maybe not. Put them in the trash.

JASON: Oh, because we didn't do word boundaries. This is why you shouldn't write code like this. Okay. So let's do ‑‑

HIRDAY: This is why you should never write RegX, really.

JASON: Let's see if that works. Let's see what we've got. One of these should match. None of them? Okay. What's something that I did say in the first one that we can ‑‑

HIRDAY: I think so ‑‑ actually, we had a fun ‑‑ someone ‑‑ one of our friends in marketing, Michael, actually set up a Twitter account that had a bunch of Good Place swears. So that user name is @JakeAwwsome, if you'd like to use it.

JASON: Yes, I absolutely would. What was it, Jake?

HIRDAY: J‑a‑k‑e. A‑w‑w‑s‑o‑m‑e. Awesome is spelt the internet way.

JASON: Okay. So now we have ‑‑

HIRDAY: Yep, The Good Mix.

JASON: Chaos. Chaos. So now we have fork, shirt, ash.

HIRDAY: Might need to rerun the query. I'm not sure.

JASON: Let's preview. Got a few in here.

HIRDAY: Yep. There we go.

JASON: What the fork? Ah, fork. [ Laughter ] This is great. This is great. Then I can also do things like this. We'll make it smarter.

HIRDAY: A lot better than what I had in mind. Which was just a list of ‑‑

JASON: Everybody love regular expressions. I love regular expressions. Okay. So now we can make a huge mess out of this and no one but me will ever be able to debug it. This is the ‑‑

HIRDAY: That's, yeah ‑‑

JASON: Shirty ‑‑ [ Laughter ] Oh, boy, this is great. So that's good enough. I'm leaving it there. We're done now, everyone.

HIRDAY: We're good. We're good.

JASON: Okay. So I'm saving. And now we are processing some tweets so the that we've got the ability to do that. So we have some of these alerted. And now I want to make this smart, is that right?

HIRDAY: Yeah. Let's make that smart. So let's scroll down. And the hidden parameter, you can also set that to be a double curly, right?

JASON: Hidden, double curly.

HIRDAY: And then we'll do filtertweets.data ‑‑ .swears. Or maybe not ‑‑ did that work?

JASON: Something like that. I did something wrong. Filtertweets.data ‑‑

HIRDAY: Cannot read properties of null. Huh. Did we run the ‑‑ so you can ‑‑ I think you ‑‑

JASON:  .data came back null. Do I need to send ‑‑ do I need to wrap that in data? Like does this need to be, like ‑‑

HIRDAY: That's a very good question.

JASON: Data.data.map.

HIRDAY: So let's run this really quickly. Let me see what the response is in this preview window. Ah, okay.

JASON: So this is just a list. So I need to return back, like ‑‑

HIRDAY: Oh, no, that's fine. I think we can say filter tweets of i.something.

JASON: I gotcha. Filtered tweets. We're going in here. .swears.

HIRDAY: Did that work?

JASON: Un‑defined always. What am I doing wrong?

HIRDAY: Let's find out. So if you open up the left sidebar, so at the top, you see the sidebar options, right?

JASON: Left sidebar.

HIRDAY: Yep, perfect. This actually contains a lot of debug information for you.

JASON: Oh, cool. Okay.

HIRDAY: We can look for filtered tweets in here, maybe. That's the state. So there's two tabs in there. There's explorer and there's state. Yeah, perfect. So filter tweets. Data is null. Yeah.

JASON: Query.

HIRDAY: Did we ever save and run it or just keep previewing it?

JASON: Good question. Let's filter tweets. Close this one up. Run. Okay. So then when we go back out here ‑‑

HIRDAY: Yep.

JASON: ‑‑ we get our filtered tweets. Data. Okay. I don't know what that was. Maybe I changed it and then never saved it or something.

HIRDAY: Possible.

JASON: Okay. So that should be ‑‑ now we should have filteredtweets.i and swears. And it should work.

HIRDAY: It should work.

JASON: No, why are you like this? Okay. Let's look at thing again. Filtertweets.data.thing. Yep. That's why.

HIRDAY: Oh, that's right. My bad. Perfect. And then not in front of it, right? Because if it doesn't swear, you want to hide it.

JASON: Oh, you're right, you're right, you're right. Okay. So then we want to do ‑‑ it was this one.

HIRDAY: Yep.

JASON: And I collapsed it. These?

HIRDAY: The not would have to be inside the double curlies.

JASON: Oh, I gotcha. Perfect.

HIRDAY: And then that's gonna ‑‑ the indicator is just gonna show you when it's ‑‑ there we go. Nice. So if you scroll now ‑‑ nice.

JASON: Nice.

HIRDAY: So, you know, we can just preview what we have so far, by going into view mode. Yeah.

JASON: Preview.

HIRDAY: Perfect. And then let's enter your Twitter username, or JakeAwwsome.

JASON: Did I forget to save that?

HIRDAY: That should have auto saved, but maybe.

JASON: Okay. So we're gonna edit. Coming back.

HIRDAY: You can set the default value if you'd like there.

JASON: And I think I ‑‑ what don't you like?

HIRDAY: Oh! Okay. So here is what happened there. So you'll see we're referencing the filtered tweets there, but we've not actually set the filter tweets query to run automatically when the get tweets runs.

JASON: Oh, okay. That makes sense. So then we close this. We go in here. We've got ‑‑ oh, wait, here.

HIRDAY: Well, let's go to tweets, right? And then scroll all the way down. And then on success, you can say run filter tweets. You can set up your own dependency graph here.

JASON: Nice. Debounce. Is this in seconds?

HIRDAY: I would not mess with that. But maybe other time play around with that.

JASON: Gotcha. So I will close this up, and we will run it again.

HIRDAY: Mm‑hmm. Perfect.

JASON: And now it's actually working. Okay.

HIRDAY: Now it's actually working, yeah.

JASON: So then if we preview ‑‑

HIRDAY: Yeah, it's not gonna be debounced, so it's gonna hit you for a little bit. I think it's A‑W‑W. Perfect.

JASON: There we go. And now we can see. There's our swears.

HIRDAY: Brilliant.

JASON: That's great. Okay. So, I mean, this is pretty powerful stuff. And then, you know, we could also do something where we, like, further filtered to say, you know, like, we have identified that there are tweets with swears. Let's only show the ones that don't have swears so that we've got, like, a clean view. Or let's only show the ones that have swears so that we can moderate or something like that.

HIRDAY: Yep, exactly. That's right. Yeah. Yeah, and you can imagine, like, the list view container having a button to, like, either mark this as a flagged tweet or a not flagged tweet or, like, a review modal that pops up even, allowing you to do a bunch of different options on the tweet. Censoring it, you know, whatever. I don't know what plans Elon Musk has to Twitter, but...

JASON: I just saw we got a raid from Rockstar74. Thank you very much for the raid. Thanks, everyone. It's free real estate sounds like an inside joke I want to understand more of. Question in the chat. How much is the service after 14 days?

HIRDAY: Yeah, we have plans starting at $10, peruser, per month. You can find more info at retool.com/billing ‑‑ slash pricing.

JASON: All right. So there is some info.

HIRDAY: We also have a free forever tier.

JASON: So this is reuse up to 5 modules. If it's just you, you just want to try something out, you can probably get by with this. And then this is if you want to get into additional features.

HIRDAY: Mm‑hmm.

JASON: Gotcha. Very cool. Very, very cool. All right. So we've got this built. I want to visualize this data. So what if I want to show, I don't know, let's say a chart of what percentage of these tweets are swearing?

HIRDAY: Yeah. Let's set that up.

JASON: Okay. So I see a chart. So I'm just gonna drag this in and let's see what kind of chaos we can ‑‑

HIRDAY: Yeah, perfect. I was going to say, don't drag it into the list view.

JASON: Okay. So then what I'm going to do is ‑‑

HIRDAY: I think this is a Twitter username so we have some data in the state.

JASON: So right now it's in the data source. Should I add ‑‑

HIRDAY: Oh, I was gonna say, you know, the Twitter username, the text input that we have. Let's enter something in the actual ‑‑ sorry, the ‑‑ yeah, right there.

JASON: Oh oh, gotcha, gotcha, gotcha. Okay. Oh, boy. Keep up.

HIRDAY: Oh, no. There's, like, you know, auto refresh could get bad, like, really fast.

JASON: Yeah, I think the debounce is probably a good idea. All right. So I've got a ‑‑ text input 1. That one's good. I'm gonna actually set a default value of this so that we don't have to keep doing that.

HIRDAY: Yep.

JASON: And then come back out here. And now we've got ‑‑ I want, like, data sources, filtertweets.data.

HIRDAY: Mm‑hmm.

JASON: And then I've got a pie chart.

HIRDAY: Yep. I don't know what this ‑‑

JASON: Nope, that's not right.

HIRDAY: Maybe if you go into filter and you set "square" as false for the rest, maybe it will pick up the label there, actually. So right now, we're only seeing the ‑‑

JASON: Good call.

HIRDAY: Queries for ‑‑

JASON: Okay. So let's save that. And then ‑‑

HIRDAY: Let's run it.

JASON: And then we will try all of that again. We'll do filteredtweets.data.

HIRDAY: Mm‑hmm. I don't think we ran the query after saving it. You, that's ‑‑ I think you can probably take it back to the teams.

JASON: Reload. There you go. 100%. So my value labels are not great. So let's go here. Swears.

HIRDAY: Nice!

JASON: Okay. 30% true, 40% false. All right. So there we go. We did it. [ Laughter ] I thought that was gonna take more work. So then I can say, percentage of tweets with swears.

HIRDAY: I'm also surprised at how little work that took.

JASON: And this is the great news, right? I love it when, you know, just getting pleasantly surprised by features working. [ Laughter ]

HIRDAY: Uh‑oh, you put that in the header.

JASON: Oh, no. I'm gonna get there. I got there.

HIRDAY: Nice.

JASON: Make this a little bit taller, and look, we've built a dashboard, everyone. So now I can go out here. And look, it's a dashboard.

HIRDAY: Amazing.

JASON: I like this. This is great.

HIRDAY: Yeah. Well, I'm glad we had some fun. You know, I think one of the ‑‑ so we did the, like, you know, connecting to various data sources. We did the, like, getting data into your UI seamlessly. I think one feature ‑‑ I don't know if we'll have time to explore ‑‑ but, you know, really differentiates Retool is the ability to write back to your data sources. So if we were to set up, you know, like a Twilio resource or something that says, you know, tell Jake Awwsome's mom that he's been swearing a lot on Twitter, and it messages his mother, right? You can set up action buttons that trigger these API requests or these DB requests. Twitter can update their DB being like the a happy‑go‑lucky user ‑‑ a trigger happy user with swear words. Let's flag their tweets in the future. You can have an API request that says, you know, send an email to this user saying, you've been swearing a lot, you want to tone it down, whatever. So the write back part is also really, really powerful. Yeah, if we have time, we can explore it. If not, I just wanted to mention it.

JASON: I think we are out of time today, unfortunately, but there is a lot of very cool stuff we can do. Also, we're learning how bad I am at regular expressions. But it is cool that it's just kind of working right away, right? And so that I find really exciting. Because we're able to just very quickly, you know, get a quick analysis. Like, hey, how how many people are talking about our company? Or something like that? I know that there's start‑ups specifically around those things, but this is pretty dang cool. Oh, Kristen Bell's Twitter would actually be a good one because she talks about The Good Place a lot. Let's see if ‑‑ has not talked about The Good Place in the last 100 tweets, unfortunately. [ Laughter ] API‑driven boop jar. I love it. But you can see some very cool things that happened here. If I go back to the app, what you were mentioning is that if I go into this, was it the query?

HIRDAY: Mm‑hmm.

JASON: Then down here, I can add things like ‑‑ if I added a success, I could do something like trigger a query or go to a URL or, you know, show a notification. Like any of these things that we can do could ‑‑ confetti. [ Laughter ] That's also really fun. So that would mean that I ‑‑ like I could do literally anything based on this data. Because I can just write an arbitrary JavaScript function to run.

HIRDAY: That's right, yeah.

JASON: Very cool. Very, very cool. All right. Well, where should people go if they want to learn more about Retool?

HIRDAY: We have a Retool docs page with a bunch of tutorials, you know, to get started. We also have Retool University on there, a quick start, you know, all of these are great places to start off with. To give you a real sense of the power of Retool. Really, the best way is think of a fun idea, start building the app, and start looking up things you don't know how to do. The best way to learn things in this field, and I think the same applies for Retool.

JASON: Yeah. Very, very cool. So, y'all, this looks like a lot of fun. I hope that you go out and give it a try. See what you can build. If you do build something cool, make sure you share it with me and with Hirday. You can follow Hirday on Twitter at this URL. And make sure that you, you know, go and do that. Like I apparently am not. So there we go. Click that button. While you are checking out things on the internet, make sure to give a shout‑out to our captioning. We've had Jordan here with us from White Coat Captioning all day, taking all this down and making sure that this episode is more accessible. That is made possible through the support of our sponsors, Netlify, Nx, and Backlight, all kicking in to make this show more accessible to more people, which means a lot to me. While you're checking out things on the Learn With Jason site, make sure you head over to the schedule because we've got some good stuff coming up. So May is going to be a conference month for me. I am all over the place. I will be at Future Stack in Las Vegas next week. So if you are gonna be there, make sure you come up and say hi. I'd love to see you. I'm going to be doing the Future Hack ‑‑ Future Hack. There it is. So if you are interested in that, you can come out and do the Future Hack. A bunch of prizes. It's gonna be a lot of fun. Lizzy Siegel and a bunch of other folx are gonna be there. Make sure you come out and say hi. Then I'm going to be at Remix Conf. Oops, can't spell. Here is Remix Conf if you want to go hang out at Remix Conf, that's also gonna be a lot of fun. And then I'm gonna be at Render ATL, so definitely come out and say hi if you are going to be in any of those places. They're all going to be a blast. I think there's still tickets left for all of them. If you're in the area, want to go learn something, there's gonna be a bunch of great people at these spots. Make sure you go grab your tickets. If you're over in the London area, there is another event going on right now called the Headless Commerce Summit. If you want to go meet up with folx in London, that one is happening right now. And if you want to go, you want a little discount, maybe drop me a DM or tweet at me and I'll get you a discount code. All right, y'all, I think that's it for today. So, thank you very much, Hirday, for spending some time with us. Chat, as always, thank you for hanging out. We're gonna go find somebody to raid. We will see you all next time.

HIRDAY: Thank you, Jason.