skip to content
Home

The Final Taco Showdown

with Emma Bostian

Last time, Emma and Jason built a form and asked you to settle their Taco Bell debate. This time, they'll visualize the results and determine who has the best taste in tacos. 🌮

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 we're bringing back to the show the wonderful, but terminally misguided Emma Bostian. Emma, welcome back to the show.

Emma: A thanks for having me back. I'm so excited to destroy you.

Jason: [laughing] -- I am very much looking forward to this. This is going to be great. For those of you -- actually, before we do anything, before we start, Emma, for anyone not familiar with your work, do you want to give us a little bit of a background?

Emma: No. I'm kidding. I majored in sarcasm. So, I'm an American software engineer. But I live and work in Stockholm. I'm an American immigrant to Europe. I work at Spotify as a software engineer. I build the desktop application. I like to make fun content about CSS and resumes and all those fun things. I'm excited to talk crap with you today.

Jason: You have a book coming out on that, right?

Emma: I have a book coming out on the interviews process, and hope to have it published within two weeks. It's going to be great. Technicalinterviews .dev.

Jason: Technicalinterviews.dev. Let's drop that link. Technicalinterviews.dev. There it is. That's a beautiful looking site.

Emma: thank you, the egghead subsidiary team built it for me.

Jason: This is a wonderful looking site. And you can also follow Emma on Twitter.com, Emma Bostian. There. Excellent. Okay. So, is this Stockholm here in your header?

Emma: Yeah, it is. Isn't it so pretty?

Jason: That's beautiful, yeah.

Emma: It's been snowing all day. It's beautiful outside. Not that I've left my house.

Jason: It's raining like -- raining pretty bad in Portland this week. I have mostly been an indoor pet. It's, you know, I'm --

Emma: As long as it's not raining men I think you'll be okay.

Jason: We were just laughing about that the other day. That song came on, like, It's Raining Men. We were thinking about how funny it is that when that song came on, people were so excited. Oh, it's raining men. And now when that song comes on, oh, please, Jesus, no more.

Emma: I'm here for it. I love it.

Jason: I was thinking more of the concept of men raining down from the sky.

Emma: Who wouldn't want that? Anyway. That's not -- that's the not safe for work Learn with Jason.

Jason: I see Prince is on board with raining men as well. I was thinking metaphorically into my mentions on Twitter. But yeah. Whatever way you want to take it. Good for you. Okay. So, let's start this episode with a little more smack talk. Because the last time you were here, we were working on a little app to settle a debate. And that debate was: We wanted to -- let's get up here. We wanted to talk about your choices. Taco bout your choices. And what we built was an abilities to determine whether or not Taco Bell is better than real tacos. Because Taco Bell is not real tacos.

Emma: I know, it's better. It's like the epitome of taco.

Jason: And so, the way that this app works is that you go in here and look at a picture of a taco and say, look at this a taco. This taco looks delicious. And then you rate it as a delicious taco. And then look at this taco, and, oh, that would give me bathroom problems. Rate it low. That's a lot of cheese, it looks good. But I know what Taco Bell does to their meat.

Emma: I feel like having bathroom problems is not an indicator of a great taco. Experience on the way in and on the way out!

Jason: Okay. So, then you continue through. You rate these. And then when you get to the end, it saves our tacos. And what that's doing here is it's putting the tacos into a database. And so, the database that we've created goes here. And it serves these up and we can see what the ratings are. So, like, here's a Taco Bell taco. It's marked as true. And the score of 3, right? And then you can see down here, like this one was rated 5. And that's not a Taco Bell taco, and so on and so forth. So, what we wanted to do today was figure out how we can get our tacos to visualize in some way. Because where we ended last time is, like, we're done here, right? Like, we voted. But nothing -- nothing happens. We send off our request. So, let me reload the page. And if we go through and rate all of these tacos, when we get to the end, it should be sending a request to add a response. Which it does. There's our response. It sends off -- so, what it actually sent is this array of responses here. And that gets put into Hasura. And we get back an okay. Okay. It worked. Okay. So, from that, what we want to be able to do is get some data out of Hasura. And so, what I think we can do here is -- like Hasura's really powerful in that it's just going to let us do a bunch of stuff by default, right? And so, I'm definitely not reading -- yes. I have sanitized the inputs here.

Emma: That's my co-worker/arch nemesis. And he is a troublemaker. It's a good thing you did that.

Jason: Let's take a look. I think we're only allowing -- we're only allowing integers. So, yes. It is --

Emma: That's good.

Jason: Yes, it is sanitized in the sense that you can't put troublesome things into it. Although, honestly, if you can hack a database by adding numbers into it, I kind of want to see it. Because I can't really imagine how you would -- if you know how to do that, send me a DM. Let's play with that on a stream. That would be super-fun. I know, famous last words. But let's talk a little bit about what we can do here. Because what I want to do is I want to use this feature of Hasura Hasura called subscriptions. And I'm going to have it just give us a list of our Taco Bell tastiness score, good. Now, let's run this. And now any time someone votes, we get that list of votes.

Emma: Oooo...

Jason: Right? Are people just voting like a lot right now?

Emma: This isn't the archive of all the votes we had?

Jason: I don't know.

Emma: I mean, it must be.

Jason: I thought it was gonna update. It should be updating. Yeah, like it's running right now. And so, we should see that the updates are coming in. And so, basically, what we can do now is I'm pretty sure we can write some reactive -- I can dump the database and retry, actually. Yeah, why don't we do that. Let's empty it. And we can... what if I just want to, like, empty it straight out? Is it gonna let me do all of that?

Emma: You're gonna delete all thousand requests.

Jason: That seems like a lot.

Emma: Don't do it. Don't do it.

Jason: I could write a SQL query, but --

Emma: We've got about a hundred. We were at 900 when we started this stream.

Jason: Okay. Wow. So, People have opinions about tacos. Oh, yeah, we're seeing a bunch of folks in here. If you would like to vote on your tacos, we-need-to-taco-bout-your-choices.netlify.app. And vote for tacos. That's the general idea, but I want to take it one step further so that once you vote we can start raining tacos down. So, what we're gonna try to do is I think do some math to figure out who you voted for first and we'll see where we can take it by the end of the episode. So, let's jump into the code here. We have got it up. Here is what we built last time, right? We have got our array of tacos. And those are all saved as images. We've added a flag for whether or not it was a Taco Bell taco. And then we used React hooks to keep track of the responses, to keep track of the active taco, to keep track of the tastiness score and to keep track of whether or not we had completed the questionnaire. So, if I run this locally, which to do that -- do we use create React app?

Emma: I thought so.

Jason: Yes.

Emma: I thought so. is it NPX -- yeah.

Jason: Yes. What I'm going to do. Let me make this a little bit bigger. I thought I zoomed out at some point. That was very confusing. Let's do a Netlify Dev here. And that's gonna pull in our environment variables from Netlify so that we don't have to pull them in ourselves. There we go. Okay. So, here is our -- our setup. And so, what I think we can do, I don't think we got around to it, but I'm pretty sure we have this isDone. I don't think we used that really --

Emma: Yeah, we do, but -- yeah. Okay. This is what we can replace.

Jason: Did we forget to set this?

Emma: Yeah, I think so.

Jason: Set isDone-true.

Emma: No, we do set it, no?

Jason: Why is it not working?

Emma: That's the bane of my existence with this career.

Jason: So, if we click through all of these. Oh.

Emma: Yeah.

Jason: It works. I think our last deploy didn't work. So --

Emma: Ah.

Jason: I bet something goofy happened that we can check.

Emma: Oh, yeah, the last deploy didn't work, yeah.

Jason: This didn't work and I'm not sure why. We'll figure it out when we get to deploying. What I want to see here, let's see if we can get a GraphQL subscription running and see if we can see something on the page.

Emma: Cool.

Jason: Do you have a favorite GraphQL client?

Emma: I don't work with GraphQL on a day-to-day basis. I think I use Graphical. Is that similar to what you're talking about?

Jason: Yeah. That's good for visualizing these. The nice thing about the client is they'll give us React hooks.

Emma: Similar so Apollo?

Jason: Apollo is big, Chad, do you want to see Apollo? Urkel? Anything in particular?

Emma: Can you explain what a client does? Because I still don't understand this.

Jason: Yes when you send an asynchronous request with JavaScript, you use the Fetch API. The Fetch API is acting as the client. With SQL, you can with send the queries, but there are a lot of things not ideal. Look at deduplicating things, if you're Spamming the GraphQL backend. And doing things like subscriptions, you have to handle web sockets and receive. So, GraphQL is a frontend library to handle that so you can say I wanted to send a query and they can do the rest.

Emma: I see.

Jason: Let's see. Urkel. Already done lots of Apollo. Okay. Great. Let's do that. What I would like to do is I would like to set up subscriptions. Here is how to do subscriptions in URQL. Let's install it. We're going to npm install URQL. I need to check if I need other things, don't I? Basics. Getting started. We need GraphQL as well. Is it like Postman? It's not like Postman because Postman is an appear for sending and testing requests. GraphQL client is more like a library for letting your app in the browser actually manage your queries if that makes sense. I think this will make a little more sense when the code starts to come together. It's sort of like if you have ever used Axios or React Query, if you haven't used React Query, there is an episode that we did on this. Go to LWJ.dev and we will find Tanner's episode. Where is Tanner? Tanner is -- you know what I should do while I'm here before Tanner? We have live captioning happening right now. I was so excited about tacos that I forgot to mention it. We have Amanda doing live captioning on LWJ.dev. That's made possible through the sponsors, Netlify, Fauna, Auth0 and Hasura to help make this more accessible to more people. I deeply appreciate that. With that, let's will find this episode here. And find Tanner. What up, website? Why are you going slow? Tanner. Here it is. React Query. Here is the episode. You can go see that if you want to see it. React Query is also a kind of a client for making different types of queries. And URQL is a flavor of that that is specialized for GraphQL. Oh, my goodness. Come on. Chat, you want to play a little elevator music? Oh, you can do it. Come on, little compooper. Okay. There we go. So, let's add GraphQL. This one should be much faster. Is my -- get out of here, Slack! Unacceptable.

Emma: My dad today was like, oh, we should migrate our family chat into Slack. That is not going to happen.

Jason: Please, no.

Emma: Under no circumstances will I every do that.

Jason: I could maybe see Discord. I like Discord --

Emma: No, I can't -- I don't want any of those apps in my personal life. That's what happens when you have a dad that's like an engineer.

Jason: Yeah, my dad's an engineer. But he's like the crusty C# engineer who doesn't want to do anything new. So, I'm -- I'm pretty okay with his aversion to technology.

Emma: Yep.

Jason: Okay. So, we have set up. Now let's get to this subscription thing and let's see if we can make this thing work. So, this, hopefully, will be a straight copy-baste. Now, I'm going to copy-paste it and then we can step through what it actually does. So, I'm going to go up here.

Emma: I love that we do this all in one file, too. It's great.

Jason: You know, when we're learning.

Emma: Yeah, abstraction at this point is not worth it.

Jason: Yeah, I find it very stressful. So, looks like we're missing a couple things to start. We have this forwardSubscription. It hasn't shown us what that is yet. Let's look at what it means. And it looks like we're going to need something else. Oh, this is from Apollo. So, they're friends.

Emma: How nice!

Jason: That's fine.

Emma: Frenemies, probably.

Jason: Maybe? Who knows. I don't know if there's that kind of -- it's not React, right? Like people aren't --

Emma: Yeah.

Jason: Sniping at each other. Let's see. Okay. So, we've got this going in. And what this is gonna do, we've got the client -- so, the client is the actual library. This is the thing that is gonna send queries and manage caches and dedup things and do all of that stuff. The default exchanges, exchanges in URQL, if I remember correctly, are like the way that data gets processed. So, you -- you kind of have a -- here we go. Yeah. so, the Dedup exchange. That deduplicates so you don't send the same query three times. It has a cacheExchange to see if you have run the query and get the results of the cache instead of running it twice. And the fetchExchange which is how we send the fetch query. And fetch is the browser API, or a polymorph isometric or node fetch that lets you send it in either the browser or the node environment. And they have a whole bunch of other ones as well. You can run your query twice if it fails. Or do an error thing, handle server-side rendering. We're not going to worry any of that today. We're only going to worry about the subscription stuff. We have a subscription exchange, but the subscription exchange -- it basically has to have a web socket set up. All right. We're going deep into concepts here.

Emma: I don't know about any of this. So, no, I understand generally what they are. But I've never used them.

Jason: So, web sockets are if you -- like when you open a standard connection, you hit a server and you say, hey, I want some data. And the server says, great, I have some data. And it sends it back and the connection closes. With a web socket connection, you're reaching out to a server and saying, hey, I might want stuff in the future and I want you to send it to me. Great, we'll keep the line open. And you have an open connection between the server and the client that messages can be sent through. This is really powerful because it means that you get real-time communication. It also means that you don't have to send all the HTTP overhead that goes with headers and the response and like closing stuff like that goes around a request. And instead, you can just say, here's a message. And that is really, really powerful because it lets us just say, I'm listening for whenever something happens. And then we can react instead of having to say, did anything change? And the server says no. Did anything change, the server says no. Did anything change? Oh, yeah and they can react. It eliminates the need for polling. Okay. Now that welfare the subscription server web socket, which is that's for. I'm going to copy that WS and add in here. And then our forward subscription is going to just add a .request for our operation. I'm not going to explain what this does because I have a shaky understanding of it myself. The way that I understand this is that the subscriptionExchange is more or less just taking a subscription operation and sending it through to something that can handle web sockets. And then the web sockets are like passing those messages back and forth. And then when we get something back through the web socket, it gets turned into data that GraphQL can say, like, hey, I got something. Here it is in your subscription. So, now we have to make the subscriptionClient, which we have not done. And that lives where? Oh, we got to set it up here. So, we need this thing. And we connect, true, seems like a smart thing to do. Because every once in a while your web sockets will just outright fail. And I'm gonna see -- I think we can just hit this with -- with this URL here. So, let's go to GraphiQL. And get this. And note that I'm not getting the HTTP. Because what I'm going to do is get WSS. So, this is still over SSL, but now it's web sockets over SSL.

Emma: Hmm m!

Jason: I would like to try this and see if it works. So, let's get through the rest of this setup and we'll just fire off a little query and see what happens. So, there is our exchange. Good, good, good. I don't want GraphQL-WS. I think now that we've set this up, we can -- we've got our client. We create the client. Here. And then when we want to use the client... we have to provide it. So, we're gonna get a -- oooo -- I think we need to move this up. Because in order to use a provider, we have to wrap the thing that uses it.

Emma: Uh-huh.

Jason: So, I think we need this to be up here. That's fine. Let's do that. Okay. Everybody following us? Are we... are we making sense? All right. So, while I copy/paste this, what's -- so, I've heard that if I have complaints about the Spotify user experience, I should bring those directly to you, right? You control the roadmap now?

Emma: I do. I actually just found out that I'm the new CEO. So, literally, I swear, I got this DM the other day from someone that was like, the developer portal is down. You're the only one at Spotify I know so I'm sending this to you. And then 2 minutes later, it's back up, never mind. And today, a week later, it's like, it's back down again. I don't know what the developer portal is. Leave me alone.

Jason: Just say, I fixed it. You're welcome. Flipped that button. I did the thing.

Emma: People forget that Spotify is a big company.

Jason: It's a huge company. How many people work there?

Emma: It's only a few thousand people. But I compare that to IBM, I guess.

Jason: That's fair. IBM a had the same --

Emma: Like 350,000 people.

Jason: It's like the population of what's that little? Luxembourg. The country of Luxembourg has as many people as are employed by IBM.

Emma: That's insane.

Jason: Okay. Theoretically speaking, we have now done the thing. Let's see --

Emma: How do we know if it works? If there's no error in the console?

Jason: Is it should fail pretty loudly if the provider's not working. So, let's just start it up and see what happens. Moss showing Internet. The IT Crowd, if you haven't seen it, it's like the best. Have you watched the IT Crowd?

Emma: No.

Jason: It's a BBC show about three people who work in the IT department of a big company. And it is just delightful. Okay. So, let's see if we are getting -- here's our 101. And we're getting responses. Here we go. Yeah, look at this. So, we're getting our web socket responses.

Emma: Sweet.

Jason: And so, we can kind of see here that stuff is happening, connection error. Access key recovered but not found. That's fine. We can work on that part. How do we do that? We need to figure out how to send a token. I have done this before. I'm going to cheat and look at some code that I've written. So, let's go to this -- is it socket studio? I think? Yeah. This is the code that runs the boops and the overlays and everything for the stream that you're watching at this very moment. So, let's see if I can figure out how I put together this thingy. So, here's our web socket URL --

You just got blitzed!

Jason: You did just get blitzed. Where is the -- where's the header? SubscriptionClient, yeah, that's what we wanted. Web socket URL... hm. I have many questions about what I'm doing here. So, here's -- here's the subscription. And that runs a use subscription hook out of URQL. Okay. And then that -- right. And this is -- we're doing stuff here which handles pre-rendering. Which we're not doing here, it's a create React app. It's not the build or create SSR. The American version with Joel McHale, I watched a little bit of that because they lost all of the charm of that show. It was really unfortunate. Okay. So, maybe we just try this. I'm just gonna try it. I'm going to see what happens. I'm going to install URQL React. NPM install urql/react. And maybe it was -- I'm confused as to how it tried to make a query, though. What did it try to hit? It didn't have a header. You know what I mean?

Emma: Yeah.

Jason: I'm -- maybe it was -- maybe it just tried to do like an initial connection sort of thing.

Emma: I don't know.

Jason: And because we didn't provide anything, it didn't work? It's got to be in here, though. Providing the client, showcased, advanced... how did -- how did we do this? How does it work? Show me your ways, computer. Do we have any headers in here? No. What are you doing, computer? Why? Why are you like this? I wish I knew... because this is connected -- this is not Hasura, though. So, this is straight to a thing which means that we probably need to look at this web socket transport to see if it takes headers. Because we're setting up our SubscriptionClient. I would be willing to bet there is an opportunity to send headers in this. So, let's look at this SubscriptionClient. Do you accept headers? Options, client options. Client options includes...

Emma: Hm.

Jason: connectionParams -- do you have headers? No?

Emma: That's not very helpful.

Jason: It's not helpful at all. Zero chance that this whole client doesn't accept headers anywhere. That is... right?

Emma: Yeah. I don't know.

Jason: Uuu hmm mm... I don't know. We might have to bail out to Apollo if I can't figure this out. It was all gonna be so easy. It was gonna go so well. Actually, maybe what I can do is -- is we can set up on Hasura. We can set up like --

Emma: Someone posted a link in the chat for common questions.

Jason: Oh, do they cover this? Let's see. Let's get in here and try it out. We've got headers! No. Headers? So, the fetchOptionsExchange. That returns headers. Yeah, but that still doesn't solve -- okay. So, here's what I'm going to do. I'm going to use permissions here instead. So, what we can do is go into our taco votes table and I'm gonna set up permissions and we're gonna create a role called "Public." And public is only going to be able to select things. So, we'll do -- without any checks. And they're going to be able to get... why not? We'll get these tables here. And we will save those permissions. And so, now what I should be able to do is in here, I can set environment variable. I can set a new one. And it's -- wait. What happened? My buttons. They have like an unauthenticated role, unauthorized role. And we'll just make it public. And so, what should then happen is that by default, we should be able to -- I'm not authorized. Let's -- let's start it again. Okay. This is going to work! And the reason it's gonna work is because we've removed the need for authentication. Because we're just reading data now. So, let's open this up, take a look, see what happens. We get our GraphQL. And in our responses... you don't -- no. You don't need that. Because it's... Unauthorized role is public. That's allowed. Come on, now. What's the request that it's sending? Like is it sending --

Emma: Someone in the chat's suggesting like the URL needs to be changed?

Jason: The origin. Which URL?

Emma: They said, I don't think you're supposed to pass it as a web socket URL. This one has HTTP const client with some steps.

Jason: Well, but this one's our SubscriptionClient, though. Oh, you know what it is? I bet we need to change it like this.

Emma: Oh.

Jason: Let's see if that makes any difference. Response. No messages.

Emma: Does that need to be localHost 3000 GraphQL? Or local ist 888?

Jason: We're not hitting a localhost. We're actually hitting this URL.

Emma: Okay.

Jason: Resource does not exist.

Emma: Well, that's part of the problem.

Jason: Interesting. How do you not exist? You literally exist. I can see you existing. Whoa. Whoa! Oh, wait, because it would only be for post. Which that makes sense. You can't get a thing. It should be WSS because that's behind SSL. And so, the reason that it's not working is --

Emma: Someone else said, localhost is not HTTPS by default. Does that matter?

Jason: It shouldn't for the case of testing. Because usually localhost gets exempted from the SSL requirements. Hmm... I wonder why you're like this right now, computer? Did everybody think they were coming in for a real rocky debugging ride today? Because that's what we're doing! Okay. Let's see what we can break down on this. Let's see if we can get connected without the subscriptions. Right? So, let's see if we can just make like a query. Because if we can do that, we can start to figure out what's going on with everything else. So, subscriptionExchange is defined, but never used. That's fine. We can comment this out, comment that out. Okay. So, then in here, what we would want to be able to do is get -- would you import the -- we need the URQL React stuff. So, basics, query. We already have a use query from URQL. So, I can import use query from URQL. And then we can try something like get the -- just a basic query. So, let's head in here. And enter query. And our query is going to be for taco votes. Yeah. That makes sense. Why are you still under subscriptions? I said here.

Emma: Oh, so, basically, okay. So, subscription is saying any time there's a new vote, recalculate the results.

Jason: Yeah. Exactly.

Emma: Okay.

Jason: This query should work if we grab it. So, I'm going to grab this query. I'm going to look at the URQL docs again for how it actually works. And when you use a query, you get a result and that's the only part that I think we're gonna use today. So, let's do that. So, we get a result. And that's gonna be the result of useQuery. Right and then we can make this a little bit more formatted so we can read it a little more easily. And then I'm going to do my favorite type of debugs which is just to use a pretag and dump that thing. And the null 2 formats it a little bit so that it looks nicer. Let's refresh this page. Fetching true, fetching false, combined error, Hasura key. You're supposed to be able to fetch, though. I wonder why this isn't getting picked up? Because I set the role to public.

Emma: Yeah.

Jason: Right? And then we're trying to select, not do anything else. So, that should work. And that means. I can turn these off and I can do like an X, Hasura role public. And that should change... But we don't need that -- we shouldn't need that to do... interesting. So, I have to send that key no matter what? Because I don't like that. Hm. Okay. So, maybe what we can do for the sake of this one is -- oh. God, okay. I'm gonna do a thing and I need everybody to not be terrible. Because I want to be able to move forward, but if I do this, it means that this is about to get open it to everyone. Which means you can all go in and mess this up for us. So, please don't. I'm gonna remove this variable. You hackers! You dirty hackers! Okay.

Emma: This is gonna go real good.

Jason: This is when we find out if the chat is really in with us or just wanting to cause chaos. Because what I want to do, unauthorized role, yeah -- but, see? I did this. You're frustrating. Okay. I'm doing it. Okay. We're putting this back in. All right. And it says error.

Emma: That's not helpful.

Jason: We're broken right now? Or what's the deal? Is this broken?

Emma: You broke all of Hasura, didn't you?

Jason: But wait. How? Project has a configuration error. Please contact support. I do not. I didn't do it.

Emma: That's like the least helpful error message.

Jason: Now are you telling me that I'm broken? Okay. So, let's try this unauthorized role again. Public. Restarting --

Emma: I love how supportive --

Jason: This is what I want. Restarting --

Emma: I love how supportive Chrisbiscardi is in the chat, big oof.

Jason: Chris is one of my favorite people because of that. Take one for the team. We're going to refresh, get in here, it's going to give us this public role. And it says no schema available. Which means that -- so, we do need one of these. So, I have to send that secret no matter what, huh? But that's really -- hm. That kind of defeats the purpose of having an admin secret if you have to send it with everything.

Emma: Yeah.

Jason: No! Well, unfortunately, I don't think the problem is URQL here. The problem is that we need this -- we need this to be open. Which I thought was gonna work. So, I'm going to do what? All right. I'm just going -- I'm going chaos mode because I want this to work. This is not the way that we should do this because I need it to be -- like, this is not secure. But what I want to see is if we can get this subscription running and at the moment, I am -- like we -- what we need to do is set up actual roles and access keys. But what is happening right now is obviously not that. There's literally no way that's possible. What? What? How?

Emma: This is just...

Jason: We straight up didn't lock this thing down. Look, you're giving me a big -- yeah. That's the whole goal. I want to be able to hit this thing. Cool. So, yeah. I think we might be -- might be a little hosed with the -- with Hasura at the moment and I need to talk to some Hasura experts to figure out what I did wrong.

Emma: We're gonna livestream our client call with Hasura.

Jason: Oh. We need -- yeah. Now we need to taco bout my choices.

Emma: I think that means I win by default.

Jason: Wait, hold -- okay. Hold up. You hackers! You dirty hackers! Let's turn this back on. And what I'm going to do, is just put that -- we will send that header, much to my chagrin. And I'll figure out what the right way to do that is. Unauthorized role, yeah. Stop trying to help, thank you. So, here's our console. Okay. We're logged in. We can do a thing. And if I set Hasura role to public, it drops everything out which is not what we wanted. What? Oh, god. Oh, god!

Emma: Did it just delete the database?

Jason: No. You know what I have been doing?

Emma: No.

Jason: I have been changing the wrong project.

Emma: I just saw that. Why did no one else see that.

Jason: I think I just broke my stream overlays. Oh, no! Okay. Well, that makes me feel slightly better. Okay. So, here's -- here's why we stand. The problem wasn't URQL. The problem wasn't Hasura. The problem was me.

Emma: [laughing]

Jason: Jeez. Okay. So, the good thing about this is the only thing that I did was change that -- that secret. You hackers!-I can fix that.

You dirty hackers! So, that is fine. I can fix that for sure. I'll just go over to this other project where I have that old secret written down. Oofta indeed! And over here somewhere. You know what? I'm going to fix that later. We might just be a little bit broken. And that's okay. But it does look like the boops and stuff are working. So, it's at least not broken now. It will be broken later. And in the meantime, I'm going to go to the right project, about taco choices. Oh, my god. And we're going to try all of this again using actual settings. So, here we go. Environment variables. I'm going to set an unauthorized role. To public. Oh, my god. I can't believe I did this. We're gonna add that. Now --

Emma: Oh...

Jason: This is not the wrong one. This is Taco Choices. So, now we have our default role is public. And we get -- oh, it works. Why? Okay. So, that was a great use of our time.

Emma: I mean, I'm a little offended you're wasting my time.

Jason: I'm offending myself right now.

Emma: To be honest, I'm sitting here and I didn't notice either.

Jason: Jesus. Yeah, where were you, chat? You could have seen that.

Emma: There are 82 people on this call and no one saw it.

Jason: You're killing me. No, but this is -- I need a full retraction here. This was not an URQL problem, this was not a Hasura problem. This was a me problem. I was looking at the wrong project and actually, it's great because like let's step through what happened. What up, chat? What are you ahemming? So, the thing that happened is we had this Taco Choices app. And what I wanted was for if you tried to access the GraphQL API and you did not have a secure token, I wanted you to only have access to a subset of things. So, you can only get with, whether or not the taco, the taco's ID, the tastiness score and whether or not it's Taco Bell. That's all I want you to access by public. And you can only read it. You cannot mutate data. You can only read it. And a subscription is a live read. That's what I wanted. That's what I was going for. What I did was I updated the wrong Hasura project with this unauthorized role. And then I was confused why it wasn't working. So -- so, basically, yeah I don't know that they could have made it nor clear. Look at that. It's right there. I was just editing the wrong thing in the wrong place. Part of this could have been error messaging. But ultimately, I think I just needed to read what we were doing. Okay. Now that we've done that, all of that excitement, let's -- let's just maybe try this again. So, let's add the subscription exchange back in. Let's add our subscriptionClient. Get this thing back in there. And here we go. So, we've got subscriptions. And that's all good. That's what we wanted. We are now wrapping our app. And that should mean that in our URQL docs, we should be able to find a use case for React and Preact. The use subscription case comes right out of URQL. That's wonderful. And that means if we just change this to use subscription, and I change this to subscription, what should theoretically happen is we should see in our network tab... responses. So, if I go in to our app now, which is right here. Yes. And I refresh the page. And I'm just going to do, do, do [singing beautifully] -- I have now saved. And we should see a new subscription and there are -- are we getting messages? So, we've got a bunch of these. Fetching is true, data is Taco Bell. Data, payload. Okay. So, let's take one more look at this. I'm going to try one more time. Boop, boop, boop, boop, boop [singing again! Lovely] -- there we go. Now we're getting updated taco. As votes go in, we will get those votes in real-time. This is really exciting. Because what it means is that as we're doing that, we can do our result here. We'll let us do like a useEffect. And our useEffect can be triggered on any change in the result. And for now, we can do something like... new tacos. And if we go out here and look at our console, every time somebody votes, we should get a new new tacos. And we can see the count goes up to two, if people continue to vote, it will go up to three and so forth. Now, to actually use this. What we get back is data. In our data, we get taco votes. So, we can do something like... okay. So, here's where I'm going to need your math brain. If we want to determine how -- so, if like we've got our votes, right? Our votes are gonna be result.data.tacoVotes and this is going to be an array. And I'm just gonna set this up so that we don't have to do -- we're just going to assume this is going to work. We're not handling failure cases or anything like that. And I guess we could just default to an empty array if something goes wrong. Okay. So, our TODO here is to figure out who is right about tacos and who is Emma. So, if we want to do this math --

Emma: Yeah, I was originally thinking like a reduce function would be good. But that would, I think require two passes through all of that data. So, do we want to -- oh, shoot. Like, this is not going to be super duper performant. I guess we have a thousand results right now.

Jason: I think we just kind of eat that. Because what we should be doing --

Emma: Okay.

Jason: Is setting up an intermediary or an aggregate.

Emma: Filter out Taco Bell versus taco. Do an array filter, pull them out into two separate arrays and reduce the arrays to the total sum of the taco counts and divide it by 4 for each.

Jason: So, do something like --

Emma: Oh, a reduce with two values in the accumulator. One for Taco Bell scores and one for non-Taco Bell scores. That's a great idea. I've never used two values in the accumulator.

Jason: Okay. Let's do scores. And that will equal votes.reduce. That's going to give us an accumulator. Our current value and it's going to do stuff. And our argument is gonna start out as a -- it would be like tacoBell and notTacoBell? That's what we're thinking?

Emma: Does it have to be an object?

Jason: It could be an array, but probably easier to do an object, you think?

Emma: Yeah, probably.

Jason: I think we could do whatever.

Emma: Yeah.

Jason: But in order to be a little more visually set.

Emma: Okay.

Jason: To do that, we would want, val.isTacoBell. Then we would say accumulator.tacoBell + = val.tastinessScore. And else -- we'll just do it in an else. We could just do it outside. NotTacoBell + =s tastinessScore.

Emma: Nice.

Jason: It's not the most beautiful code that's ever been written, but it could be worse, I guess? So, let's do one of these. We'll set scores like this. And so, we can -- probably take this and set this as our default. So, let's do a const scores and setScores. And that will be useState like this. Okay.

Emma: Yeah. Do we need to return the object like in the reduce function I think we need to return.

Jason: Oh, we do. Yes. That would have been -- that would have been the rest of our episode is me trying to figure out how that worked.

Emma: Yeah.

Jason: But, yeah. So, there should work, right? Where we'll -- I -- I think this will be good? And then we'll -- once we've done the reducer, we'll be able to set the scores. And then down here, instead of stringifying our results, we'll stringify our scores. So, let's see what happens. Whoa. Is that -- that can't be right. There's no way we have that many votes.

Emma: Well, what's that divided by five? 448853. Because they could have at most five. Oh, lord. No.

Jason: 80 million votes. Okay. No. So, we're doing something wrong. So, maybe -- maybe -- they can be stored as a string, though, right?

Emma: Plus equals 1... maybe we should just like consoleLog each? Let's just consoleLog like each value and -- or like their tacoScore and see what it looks like.

Jason: This is going to be super-messy. But let's do it.

Emma: Yeah, it is. Okay.

Jason: TastinessScore. Right?

Emma: Wait, is that what we -- yeah. We're gonna break this. Is that the value we were grabbing? Yeah. It is.

Jason: I'm just going to take that out because it's logging so much stuff.

Emma: Yeah.

Jason: I wonder, though, like, What was the length of our scores? Like let's just log that.

Emma: Yeah.

Jason: Undefined, undefined.

Emma: Ah.

Jason: That's interesting.

Emma: So, we need to make sure scores has a value.

Jason: No, sorry. That's my bad. I'm doing the wrong thing. It's supposed to be votes.

Emma: Ah, okay.

Jason: Votes. Eleven,000 votes. First of all, y'all have some feelings about tacos.

Emma: What the hell?

Jason: 11500 divided by 5. That means --

Emma: No, divided by 8.

Jason: 2200 submissions -- divided by 8. That's right, that's right.

Emma: Yeah.

Jason: Odd. We've had an incomplete number of submissions. Okay. So, this -- yeah. This is -- that's a lot. But it's not this many.

Emma: Yeah.

Jason: Which means something is going wrong with our math.

Emma: Oh, wait --

Jason: Do we need to parse int or something? That doesn't seem right.

Emma: Yeah, maybe.

Jason: You may need to filter for votes with a tastinessScore over five. Hit the endpoint. Let's just short circuit. If val.tastinessScore is greater than 5, just return. I don't like it when people do that, I don't know why I just did it. Makes it harder to track. Someone did a visualization of how you track visually down code with if statements. And when you have the logic over here, you had to track over here, over here, over here. Versus here where it's like boom, boom, boom. Okay. Oh. wait, we just need to return the accumulator in that case so that we don't break our whole thing. Okay. So, that looks a little more accurate.

Emma: Yeah.

Jason: Thank you to whoever is stress testing the system. Lots of votes in favor of not Taco Bell. Just saying.

Emma: Well, no one knows what they're talking about.

Jason: I mean, you're literally -- you would say this is being ratioed here. Three to one.

Emma: It's just you. You set up a bot to auto-vote for yourself.

Jason: No, my bot was the one that put the scores really high. The last vote -- the last vote won't fail, but it won't do anything because it doesn't get to that like scores thing. How are we going on time here? We have like 30 minutes which means we probably don't have time to do anything super-ambitious with this data.

Emma: Yeah.

Jason: But what we can do is let's get this thing published in the right place. So, let's put the score... we've got our scores, right? So, instead of doing it like this, we can do something like the people have spoken. And they believe that Taco Bell is... and then I think we can do like a little -- we could probably put this logic somewhere else. But let's do like scores, notTacoBell is greater than scores.tacoBell. And if that is the case... So, that should give us our -- like our results. And I am gonna pull this out because I want to troll you further with it. Let's do -- let's do it -- how do I want to do this? I don't really like the -- these booleans always throw me. Sure. Why not?isNotFood. That's not confusing at all to use. And then we can do like, isNotFood.

Emma: You need a -- you don't have a second on your ternary. You should just do, isNotFood and.

Jason: I was going to let you come up with something to troll me with in case.

Emma: Oh, gotcha. Oh, sorry. I would go for like undoubtedly. Or something much longer than "Not."

Jason: Is -- okay.

Emma: What?

Jason: IsAbsolutelyNotfood. Okay. How would you troll me -- if you end up winning. And this one you're absolutely right. I did that wrong.

Emma: Yeah.

Jason: I was looking at this one and got confused as to what was going on. Okay. So, here you get to troll me if you manage to turn the tides.

Emma: Hmm... that's a great -- maybe we could say that the entire city of Austin, Texas, has banned me from visiting. Wait, but that's not trolling you. That's trolling myself again. It's too late for this. I don't know. It's almost 9:00. I'm not good at this right now. Okay. Well, either way. Oh...

Jason: Okay. Let's -- we can do, Jason is a snobby hipster and needs to get off his judgey taco high horse.

Emma: I love it. thank you.

Jason: Okay. So, now what we can do is we should be able to see -- you can save and rate. And we'll get a bunch of these in here. Ah, I enjoy this very much. All right. So, let's go ahead and take this thing live so that --

Emma: Great.

Jason: So that people can see these results. Let's see what's here. We've got our package lock. Did we use yarn last time? We did. Oh, no! I'm going to remove that. And I'm just going to do a quick reinstall. Oh, god, we have URQL in here. Do we have enough time left in the episode? We'll see! We'll see!

Emma: Jason and separately his beard have been banned from all Kraft breweries in Austin. And separately his beard.

Jason: Yeah. We can include that. That's funny. � is it craft -- because otherwise it's just the processed cheese?

Emma: That almost makes it funnier.

Jason: Oh, yeah, Kraft singles beer is definitely the flavor that we all needed.

Emma: I would inhale that. Oh!

Jason: Okay. Did this -- this is -- okay. That's good. I'm going to remove -- we already did the yarn lock. I'm going to get add anything, Git commit, show results. And then let's push this thing up and let's figure out what went wrong with that build last time and see what we hit here. So, here is our build log. And if we go over to deploys, we should see our new one. And hopefully there is just gonna work.

Emma: Ah, cheese beer. Beer cheese.

Jason: Now, beer cheese I'm on board with. Cheese beer, on the other hand...

Emma: Right.

Jason: I don't know. I don't know about that. Miller Light, but cheesier. It's so funny. I'm so on board with like a backyard barbecue where I'm having a beer and eating Kraft singles. But never the twain shall meet, you know what I mean?

Emma: Okay. So, first of all, one thing I found when you move to Sweden is that -- I went to the grocery store and I'm walking through the aisles and they have a whole aisle full of massive-ass blocks of cheese. Google Swedish cheese and look at images, who the hell is eating that much cheese? I bought one day because you have to buy it in bulk quantity.

Jason: I'm going to eat this much cheese.

Emma: I come to find out, they have a thing called a cheese shovel. It looks like an ice scraper. But they literally shave off pieces of cheese. You know how we have cheese slices. They shave their own off of big blocks of cheese. Scroll down. It looks like that. They just sit there and shave off their own slices. What the hell is this? I have been doing this wrong my whole life.

Jason: I like this. This is after my own heart. When I have a block, when you take a bite out of the block, it feels wrong. It feels incorrect. But if you have the block, and slowly shave slices off. Only one slice of cheese, maybe just one more. And then it's gone.

Emma: Right. I found a cheese the other day that's called champagne cheddar, and let me tell you, did lives up to its name.

Jason: I'm very on board with that. There's a -- okay. I'm going to talk about the pandemic for a hot second because it makes me sad to talk about. But this is the thing that I miss is there are the grocery stores, like the fancy grocery stores that have the organic food and everything, they will have the deli and the deli is full of all of the fancy cheese and one of my all-time -- I realize how much of it like a boring adult I'm going to sound like right now. One of my all-time favorite activities is to go grocery shopping and --

Emma: I love it!

Jason: And hang out at that counter and say, I'm looking to make a charcuterie board, and what should I pair with it? I name come condiment in the fridge. I get to sample 18 kinds of cheese. It's kind of like shopping and lunch?

Emma: I love that. That's a great tip if you don't have a lot of money to spend on food for that week.

Jason: Ya issue not found? Why are you yarning? What have I done? Okay. I can kind of see how things went wrong here if we're calling a command that doesn't exist. Let's go in here. Okay. That's why we had a yarn lock. Okay, let's just try that again. Okay. The chat is just going off about cheese.

Emma: I actually got heartburn just thinking about American cheese while sitting here. Like, I'm not even joking.

Jason: Cheez Wiz. Oh, yeah. String cheese is wonderful. It's all wonderful. I like it all. And like I -- I usually have strong feelings about food that's processed and stuff, as evidenced by us fighting over tacos. But when I make cheeseburgers, I use the Kraft singles, like the American cheese.

Emma: You have to. It's melting cheese.

Jason: It's melting cheese.

Emma: That's what it's called over here in Europe is melting cheese. It's really just Kraft singles, basically.

Jason: A Cheez Wiz is not a smart cheese connoisseur. It should be.

Emma: Cheese Whiz Khalifa.

Jason: I went to Philadelphia years ago, and while I was there, the two places are Pat's and Geno's. And if anybody is in Philadelphia, feel free to correct me because I went in my 20s. I went with what a friend recommended. But I guess Pat's and Geno's are the big names of how to find a cheese steak. And they're like catty corner to each other. You can literally see one from the other. There's a huge line at both. We went to Pat's. And while waiting at line at Pat's, the guy in front of us forgot to order a drink or something. And they're pretty like -- our build. Our build failed because -- do not use marquee get. No! Let people enjoy things. Okay. We'll turn it off. Fair enough. We don't want to be inaccessible. But also, that breaks my heart a little bit. We'll turn this off. So, anyway, we're at Pat's, and this guy, he forgets to order a drink and he goes to pick up his sandwich. And asks if he can buy a drink, no, you can't do that. He didn't want to wait in the line again and he gets super- agitated and gets so mad that he decides to throw his cheesesteak through the pickup window at the person making sandwiches who then proceeds to completely empty the restaurant. Everyone who works there whips off their shirts and goes after the guy, and they run across to Geno's and start yelling that Pat's sandwiches and the Pat's crew was fist pumping behind. It was the most Philadelphia moment I have ever had. Did I push that change? I sure didn't. I was just talking. So, let's...

Emma: Oh, gosh. Now I really do have heartburn. But still want the cheese.

Jason: I still -- yep. I'm now trying to strategize like how can I get something really cheesy for lunch. The modern day hunt for food. What? How bad have you screwed up? Was it empty -- empty the cheesesteak place bad? This was empty the cheesesteak place bad.

Emma: Why are your subscribers so funny?

Jason: I don't know. How did I get so lucky? How did I get so lucky, chat? This one is going to work. Because we took out the Marquee.

Emma: I love Netlify, by the way.

Jason: It makes me very happy. I'm biased, by the way. Aw, look at the chat. They're just being even nicer.

Emma: I want a burger now. Is 9:00 at night too late for a burger.

Jason: No. That's a good time. I found in Europe it was hard to get good burgers.

Emma: Sweden has good burgers. It's kind of a religion. I like it simple, I don't want a lot of crap on there. I just want cheese and that's about it. You know what I'm saying?

Jason: Yeah.

Emma: I don't want bake -- well, bacon I could go for. But I don't want jalapenos. Those don't belong on there.

Jason: I'm with you. My favorite burger is the simple Smash burger. It's like griddled onions. Those are mostly for the umami. They cook down and don't have the crunch left in them. Super flat smashed Patties, lettuce and pickles. A burger sauce if you got it or something else.

Emma: So good.

Jason: Okay. Let's do a quick rating. See if this works. It should be working now. Hit those Taco Bell tacos out of there. None of them, don't like them at all.

Emma: To be fair. It looks like an ad. You could have chosen better ones. I think you skewed this.

Jason: My reason for doing this, the other taco photos we got from unsplash where they're royalty-free. The Taco Bell I couldn't find images. I erred on making them Taco Bell ads. I'm being mean to Taco Bell, but you are very much standing up for Taco Bell. And as long as they're getting the publicity, right? But this is -- hey! Look! Look! Chat turned it.

Emma: Nice! Thanks, Craig.

Jason: Look at that. Chat, whoever is running that script, turn it the other way and see if it switches back in real-time.

Emma: No! Don't!

Jason: This is -- this is fun, though. Like I love -- and like this is such a -- it's a subtle thing, right? Because we're not really doing anything live, but we are. And this is the sort of stuff that I think is really fun when you look at web interfaces is you have the ability here to do something that is like subtle, but still really engaging. And, you know, it caught my eye enough to bring me back to the page. But not so much that it like, you know, it's not doing explosions or anything. But we can and probably could in the future turn this into, you know, we could show like when somebody votes, we could have a taco pop-up on screen. Or do taco fireworks or something like that. And that could be a really fun way to make this more engaging. And, you know, maybe some day in the future we do that. Because I can see a lot of fun with, you know, physics or things like that. But yeah. Let's see. So, we have about 10 minutes left. Which means I don't think we have enough time to do too much else here. So, Emma, do you have any ideas for any last minute things? Or do you want to just open it up for some questions before we wrap it up?

Emma: Let's do some solid Q&A. Hit us with your best.

Jason: All right, y'all. What do you got? What questions do you have for me? For Emma?

Emma: Rapid fire.

Jason: Get us. Look! And it switched back. Look at it go. This is -- this is super-fun.

Emma: Well, I screen-shotted me winning. So, that's what...

Jason: I'm not seeing any questions. But that's okay. So, what I'm going to do while we're waiting for any questions to roll in, flip back over here. And another shoutout to Amanda and White Coat Captioning hooking us up with live captioning which I'm so, so happy we have been able to put together. Made possible by our sponsors. Look at that fun thing that's happening there. What is that all about? Weird...

Emma: Ah.

Jason: That's a fun little bug that I'm going to have to figure it out. There we go. There's the sponsors, Netlify, Fauna, Auth0 and has all kicking in to make this show accessible. Which I appreciate. And check out the schedule. Add it to Google Calendar and get notified whenever episodes are upcoming. We have Laurie coming in. Build a Babel plugin.

Emma: I thought that was a bagel plugin and I was like, this guy's obsessed with food.

Jason: I want to make -- someone is asking how is your German going?

Emma: [non-English]

Jason: Did you just switch between three languages?

Emma: No, I butchered my German grammar, but it's fine.

Jason: Like, I remember ham and cheese in like 13 languages. But that's like all I know in those languages. But, yeah. So, we got, we're doing a bagel, also known as Babel plugin on Thursday with Laurie. Then we've got Lucie coming on. The Prismic io's slice machine, the CMS will let out control layout by controlling the data structure and the layout on the frontend and package them up. Components back to the database. It's fun. And a little bit later on, Joel Hooks is going to join us, serverless marketing automation for React. If you have seen the new Egghead site, it is really, really cool. They have added a whole bunch of amazing stuff. You should go and look at it. I'm a big fan of -- why didn't you copy that. Copy. This one. But this is -- this is really cool stuff that -- that they have been doing. And one of the things they have been setting up is marketing information. Trying to get you content that's relevant to your interests, not just a blanket Spam you with a bunch of anything. That's not good for anybody. Let's see. Is that food stream too? All food stream streams. Next wear on Tuesday, I'm going to go live solo, I think. Because I had a reschedule Kolby. I think I'm going to keep working on that subscription overlay with the hearts and stuff. Have some fun stuff there, do some fun things. Emma, where should people go if they want to find out more about you? I'm going to replug your technical interviews to start.

Emma: Yeah, I have been putting this off. I have been really sick, I had COVID. I promise this is going to get re-released. I'm on Twitter. That's where I do most of my Internet stalking. That is it. Yep.

Jason: Most of my Internet stalking. Good, good. Everyone go follow Emma. It is a delight. You get to watch Emma argue with everyone. Usefully lovingly. Sometimes not so lovingly.

Emma: I ain't got time for arguing for real these days.

Jason: My favorite is to watch you and Kelly argue because I feel like it is -- it is -- it's like passively observing an inside joke that I'm almost part of. Because I don't quite get it, but I don't know that something is going on. But enjoy that very much. Okay. So, that I think is everything for us today. Chat? As always, you have been delightful. And thank you for not completely bombing the Hasura when we unauthenticated it for a brief moment.

Emma: That's good.

Jason: Emma argues with everyone. Sounds like a sitcom I would watch. I would agree.

Emma: That's called being my friend.

Jason: Well, thank you so much for hanging out with us today. I really appreciate it. I'm glad that we were able to prove -- I guess we should check if we've continued to prove that -- no. No. Chat has turned in your favor.

Emma: Ah-ha!

Jason: They're a defending your terrible decisions.

Emma: They should.

Jason: And I will begrudgingly let the episode end on this note. Thank you to all of you who voted legitimately, to those of you who where scripts to Spam the heck us how of it, and those doing stress testing. Emma, thank you a million times for coming back on the show. We'll probably see you again. I'm sure we'll come up with something silly to do in the future.

Emma: I'm sure we will.

Jason: Chat, stay tuned. We're going to find somebody to raid. And we are see you next time. Thanks for hanging out.