New in Vue 3: Watch & watchEffect with Alex Riviere
Key Points From This Episode:
- Introducing today’s host, Tessa!
- We welcome a special guest, Alex Riviere.
- Alex tells listeners a little more about himself.
- Alex breaks down watch and watchEffect.
- Examples of why we use watchers in Vue 2.
- Alex answers: what is watchEffect?
- How watch on Vue 3 differs to its Vue 2 version.
- The caveat to having one function for all.
- Recapping the main difference between watch and watchEffect.
- Alex defines what side effects you might face.
- What Alex finds helpful about the current docs on watch and watchEffect.
- We talk about de-bounce search and our experiences with it.
- Alex gives listeners a useful metaphor for watch and watchEffect.
- We share our weekly picks!
- “In Vue 3 we have watch and watchEffect in the composition API.” — @fimion [0:02:02]
- “With the composition API, you can now import from Vue watch or watchEffect. WatchEffect allows you to define a function that accesses some reactive value.” — @fimion [0:03:43]
- “So when we're passing complex objects to the watch function, it doesn't immediately want to be able to show you the old version and the new version. We kind of got to do some stuff to it.” — @fimion [0:08:45]
- “Sometimes watch is not the correct answer. It's a very powerful tool. It can do a lot of really good and cool things. May not always be the correct answer, however.” — @fimion [0:23:04]
Links Mentioned in Today’s Episode:
[00:00:10] AC: Hey everybody, and welcome to Enjoy The Vue. I’m Ari, and today on our panel we have just Tessa.
[00:00:17] T: Hello, I am only Tessa.
[00:00:19] AC: Fortunately, Tess is amazing. And we also have a special guest for this episode, Alex Riviere. Would you like to introduce yourself, Alex?
[00:00:28] AR: Yeah. Hey, I’m Alex Riviere. I’m co-organizer of the Atlanta Vue.js Meetup, and I’m a frontend web developer that uses Vue all the time here in Atlanta, Georgia.
[00:00:40] AC: All right, and today Alex is going to teach us about things I previously hadn't even heard of. So this should be fun. That is watch and watchEffect? Is that right? Is that what we're talking about?
[00:00:57] AR: Yeah. That is what we were talking about. We are going to talk about watch and watchEffect.
[00:01:01] AC: Okay. So what is that?
[00:01:03] AR: So in Vue 2, we'll sort of back up a little bit and we'll start with Vue 2 and then we'll go into Vue 3.
[00:01:07] AC: Ooh, origin story.
[00:01:09] AR: Yes, origin story. So in Vue 2, when you were defining a component, you could define a section that is your watch section. And in your watch section you would be able to define various properties that you wanted to watch and it would give you the old state and the new state and allow you to compare the two and then do something based off of that, right? So if you're triggering something, like some sort of effect based on that data that isn't directly related where you need it to happen every single time, unlike a computed value where it doesn't necessarily happen every single time, you could do that. And that interface still works in Vue 3. In Vue 3 though we have two sort of new methods of doing it. We have watch and watchEffect in the composition API. And so we can talk through both of those.
[00:02:08] AC: Just you know so everyone's on the same page. So like an example of how we might have or why we might have wanted to use a watcher in Vue 2 would be the user did something and now we need to ping the API for new data. Yeah?
[00:02:25] AR: Yeah. Yeah. Or another one that we do sometimes at work is you want to update your query parameters in your URL for the page that you're on, right? So it's based on the variable that you're looking at, but you don't want to be referencing that variable in the URL constantly. So you're tracking that variable, but when that variable updates, you want the URL to update as well. So if you're doing like a search or something like that where you're updating the search query as you're typing because it's, “Ooh, fancy.” Then that would be a place that you would use a watcher.
And so we have two methods for doing this in Vue 3. I believe that the original – oh, I’m going to have to look this up now. Okay. So in Vue 3, we have watch and watchEffect. These are newer APIs that we have. The way that you used to do it in Vue 2 is that you would define your options section that's watch and then you would define sort of the name of the thing that you want to watch. I believe that API is still going to work exactly the way that it has. With the composition API, you can now import from Vue watch or watchEffect. WatchEffect allows you to define a function that accesses some reactive value. So you can access – in the composition API you're able to use ref or reactive to create a bit of reactive state. You would then be able to, in watchEffect, every single time that state updates, you would be able to say, “Hey, use the value of this to go do something else that's completely unrelated to that value. This would allow you to trigger updating the URL, kicking off a search. If you're needing to de-bounce a search query or something, this would be a great way to do it. But it always gives you the current state of that variable because you are accessing the reference to it.
So the way that you do it if you're going to just sort of like talk through coding is that you say, watchEffect, parentheses and then you pass it a function. And inside of that function you would reference a piece of state that you've defined in your setup function. And Vue behind the scenes is doing some magic sauce to make it be listening to that value. So as that value updates, you're able to do something else with it.
Watch on the other hand has a slightly different interface. It has a slightly better interface than the old version of watch, in my opinion. With watch, you are able to give it multiple values. So its first parameter is the values that you want to track, right? So you can just give it one piece of state, or you can give it multiple pieces of state inside of an array.
[00:05:47] AC: Oh my God! I wished so many times that that was a thing I could do instead of just copying and pasting the same function for multiple pieces of state.
[00:05:56] AR: Right.
[00:05:58] T: And then being like how do I access this slightly nested one again?
[00:06:03] AR: Yeah. So that's big, right? Like we can just make an array of things. You can also pass it a function that returns a thing, multiple things, whatever, right? And we'll get into why that's important in a minute. So the second parameter of watch is a function and it takes in two arguments essentially. I think there's actually a third one, but we won't worry about that one too much at the moment. The two primary arguments of this function that you pass in to watch as the second parameter are the new value and the old value. This allows you to compare and say, “Hey, only trigger this update if these two don't line up. Only trigger this update if I’m going from one state to another state.” Like if you have a state machine and it's going from in progress to in review, then you can say, “Hey, if it's going from in progress to in review, then we can trigger something on that.”
Or you can do something where it's like, “Hey, if it's going from in progress to a thing that it's not supposed to be going to, don't do that,” right? You can actually reset the state if you wanted to and block somebody from doing something that they're not supposed to. So it's going to be that you can – There's a lot of flexibility in there because now suddenly you're looking at history. You're looking at like what it was, what it is. And so this is a much closer to how the old version of watch work, but you're able to pass in multiple values. So if you pass in multiple values, your new and old values have the new and old versions of those values.
[00:07:54] AC: In the watch function, how does it know which function goes with which value?
[00:07:59] AR: It all goes into the same function basically, right? So you would do watch, right? The way if we mouse coded, it's going to be that you would do watch open parentheses, the value that you want to watch, comma, a function, right? So if you have multiple values it would be array, value, value, value, value, close array, comma, function and the first parameter of that function would be an array of value value, value, value.
[00:08:30] T: Okay. So it's one function for all of them.
[00:08:32] AR: Yep. One function for all of them. Now there is a caveat with this.
[00:08:40] AC: There always [inaudible 00:08:40].
So what we have to do if we're dealing with an array, if we're dealing with a proxy or with an object, if we're dealing with a set map whatever, whatever object, fancy object that you're using. What we have to do is that this is where we need that function as our first parameter instead of just the value. So when we use a function, we're able to – Maybe if it's an object, we can spread it and it will do a shallow copy of that object and give us all of the values inside of it. If it's an array, you can also shallow copy it by doing open bracket dot dot dot array thing close bracket and it will spread that.
So we're going to make a function that returns that value and we're going to pass that in as our first parameter. That allows us to when the thing is going to change, it takes a snapshot of the current values. And then once it's updated, it takes a snapshot of the updated values and then we can compare the old and new values.
[00:10:52] AC: And that was one of the limitations with watch in Vue 2. Is that correct? The same thing?
[00:10:58] AR: I think so.
[00:10:59] AC: And I guess this is getting around that.
[00:11:01] AR: Yeah. It always got real complicated in Vue 2 I think when you wanted to do that type of thing.
[00:11:07] AC: Yeah, I definitely remember being bit by that, because like it worked like in one scenario in my app, but then another scenario it didn't work. And because it had worked, like I was like, “What is going on?” And then I was like, “All right, I remember reading that caveat. Whoops!”
[00:11:25] AR: Yeah.
[00:11:25] T: It's kind of surprising or disappointing though that it's still the case with like the new proxy system. Like you said I would have expected, “Oh, that should make it better.” And/or there would be some kind of like deep option.
[00:11:40] AR: You can still watch things deeply. So that is a thing. That hasn't changed. If you have a really complex deeply nested object, this is typically where I end up reaching for like Lodash, which is a utility library that has a bunch of ways of being able to like handle data and manipulate it in useful ways. And they have this lovely function called deep clone, or no, clone deep. That's what it's called. It's called clone deep.
[00:12:09] AC: I have definitely typed it the other way and it does not work that way.
[00:12:12] AR: It does not work that way. No. And so you can pass it an object, you can pass it an array and you just say, “Hey, here's this thing. I need a copy of it, but I need like a really deep copy of it,” and it'll go through and it will give you a copy of it with all of the values in it, but it gets rid of all of the reactivity.
I feel like this is one of those things where as more people start using Vue 3 and as the ecosystem grows, there's going to be a better way to handle this. But at the time that we are talking now, I don't know that there actually is.
[00:12:46] T: I’m also excited for the way that we'll gain like massive popularity that everybody is like, “Don't do that. It's a bad idea.”
[00:12:54] AR: Yeah. And then also – but because we're able to watch things from a function, like we're able to say, “Hey, here's the things that we want to watch.” You can also – if it's an array, you're able to go, “Okay, cool. Let's map this array and only return the values that we want, right?” So maybe if the array is full of objects, but really you're only wanting to watch this one value inside of that object, you don't have to do a full, like give me the entire object. You can just be like, “Cool. Let's look at this array of objects, and in that object just give me this one value. So it's an array of values.” And you're able to compare those rather than having to deconstruct an entire object inside of your watcher. So there's going to be a lot of interesting design pattern things that are going to come out from this I think. So it's a new age of experimentation in Vue components.
[00:13:53] AC: So I can finally stop making computed properties solely for the purpose of simplifying a watcher?
[00:14:00] AR: I know, right? I mean, yeah, that's basically what we're doing here is that we are making a computed value that is not cached so that we can watch it with our thing. So there we go.
[00:14:15] T: Okay. So to recap, watchEffect and watch are both – you give them like the things you want to watch and then a function you want to run when that thing changes, right?
[00:14:23] AR: Slight difference. WatchEffect, you give it a function and Vue automatically figures out all of the things inside of it that you're watching. But you don't have access to history. So you only have the current value of that object. So if you don't care about being able to compare before and after, watchEffect is the way that you want to go, right? Because that is the simpler way to go. But watch is sort of more powerful. It gives you more flexibility and lets you see what the value was, what it's going to be and go from there.
The other thing about both of these is that they both return a method that allows you to stop watching that value. So when you call watch effect and watch. They return this function and then if later on if you're like, “Okay, cool. We've been watching this thing enough. We can stop now.” You can call, stop watching it and it will stop without having to completely destroy a component.
[00:15:35] T: So with watchEffect, is the idea that you're watching for effects or is the idea like this is the thing you want to affect when the things that you're watching change?
[00:15:44] AR: I think it's that you are watching and you are going to have a side effect. You are going to affect something else. There's going to be an effect on something else is that. So you're watching and then going to cause an effect.
[00:16:00] T: And how do you define side effects?
[00:16:03] AR: So side effects are – okay.
[00:16:07] AC: They’re subjective.
[00:17:14] AC: So, like I don't know. For me, the example that I’ve always kept in my head for like the concept of side effects is the difference between using map or for each on an array, because map, the goal is to only concern yourself with the incoming data and output something based on the input. But with for each, you can do whatever the hell you want based on each item in that array. You don't have to actually do anything with those values. So that's how I’ve always thought about it, because you don't have to return anything from a for each.
[00:17:48] AR: Correct. Yeah. Yeah, exactly. You can have an array outside of a four each and then you can loop through on a for each and then just chunk it all into an array in a new format. You can also do that with like a filter and a map at the same time. There's like multiple ways of doing things. There's always multiple ways of like approaching problems, but you can do kind of whatever you want to in a for each and it's very helpful.
[00:18:17] AC: But that's also why some people think that for each is a code smell. I disagree, but I’m just saying there are people who believe that.
[00:18:24] AR: Yes.
[00:18:24] T: Those are people with no joy in their lives.
[00:18:28] AC: No. No. We don't want to alienate some of our listeners. I understand the argument for it being a code smell, but I also think that if you're always saying it's a code smell, you're limiting yourself because there are some very powerful things it can do that you really want to be doing.
[00:18:46] T: Yeah, I don't know about you too, but I only code using reduce. Like I don't use any other methods. I just reduce everything.
[00:18:50] AC: Stop it. You're hurting my brain. Just the word reduce hurts my brain.
[00:18:57] T: So speaking of a variety of approaches to a problem, unfortunately they couldn't be here today, but I understand that you have been thinking more about watch and watchEffect because you saw this video from – Let's just call them be who shall not be named.
[00:19:17] AR: Is he a very suspicious character that tends to lurk around here sometimes?
[00:19:23] T: Yes. That's little bean, and that's gotten you thinking about updating the doc. So I was wondering what do you find helpful about the current docs on watch and watchEffect and what do you think that you would add or change?
[00:19:38] AR: As of the day that we are recording, the documentation, it sort of gives a nice overview of how it all works.
[00:19:49] AC: We should probably specify it as November 19th.
[00:19:52] AR: Yes, thank you. So with the way that the docs are today, it's it gives the general overview. It sort of explains everything and stuff like that. However, all of the caveats I was talking about with if you give it an object to watch, it gives you the proxy reactive object. And when you get that, then you don't have this great way to compare it. And so I’m planning on hopefully here in the next bit, I say this every time on a podcast and I shoot myself in the foot afterwards, I’m going to be updating the docs hopefully and at least trying to make an effort to sort of document some of these things and like how to handle certain situations, because I feel like that's going to get kind of frustrating to newcomers who want to use this for something.
[00:20:52] T: Yeah. So how did you discover these caveats?
[00:20:56] AR: So our suspicious friend who is suspiciously not here was streaming and we were looking at a problem and he was trying to do something where he needed to compare two objects and we couldn't, while there on stream, figure out how to get it to work. And so I started digging into it and making examples of like here's how you do it and here's how you do it here and here's how you do it here. So I have a code pen with those examples that we can drop in the show notes or something.
[00:21:32] T: Sounds good.
[00:21:34] AC: So there's a code pen with these examples that show like here's how you want to deconstruct complex objects.
[00:21:42] T: So when you were looking at this API, did any like potential common pitfalls come to mind? Like could you see a lot of people making a certain kind of assumption that you would recommend that they watch out for aside from assuming that objects are reactive or that you can I guess detect changes in them deeply just because they are reactive?
[00:22:04] AR: The common pitfalls with watch and watchEffect is there's a lot of times where you're going to think, “Ah! This is the best way to handle this,” and it may not be. There may be a better way to do it that doesn't require you to watch and do something based on a value. There're a lot of times where just doing a computed value is actually the right way to go. Because with computed values, I think we all are very familiar with the syntax for computed values where you define a function and then you return a value and then that's your computed value, right? And with computed values though you can also do a get and a set. And so sometimes it's easier to watch for the set and then do something based on that. So it really depends on your situation, but that is one of the caveats, is that sometimes watch is not the correct answer. Like it's a very powerful tool. It can do a lot of really good and cool things. May not always be the correct answer however.
[00:23:18] AC: Yeah, that was definitely an anti-pattern I fell into when I first started with Vue partly because I was coming from Polymer, which had the same concepts roughly of computed and watchers, only computed was very limited in Polymer. So you ended up using watch for everything. But then I learned that computed properties were the best ever. They're literally my favorite thing in the world about Vue. And then, yeah, so over time I started taking out all of the useless watchers I put in favor of computed properties. But yeah, that's one of those things. Like my rule of thumb is I generally will only use a watcher if what I truly am seeking is a side effect.
[00:24:04] AR: Yeah, that is typically the mindset that you want to go in with, is that watch is really like I am doing something that is slightly out of the ordinary and this is probably the best way. Because if you can put it in a computed value, it should probably be a computed value. Like if you have two reactive variables and when one updates, you want to update the other. Don't use a watcher for that. Make that second one be a computed value because it should change and update every single time that you make that first one. So that is the caveat, is that I’ve seen fellow programmers at work who they will write a component and I will go, “No. Don't do that.” Because they're trying to update something with a watcher and I’m like, “No. It's not how we do things.” So yeah.
[00:25:06] T: Yeah. Ari and I I think have commiserated in the past over like that feeling of like I guess for today we can put it as watch being like the for each of the options API. Like every time I use watch I second guess myself like 10 times. I’m like, “Do I really need watch? Okay. But do I really need watch? Do I really, really, really need watch?”
[00:25:27] AC: It feels unclean.
[00:25:30] T: Yes.
[00:25:31] AR: Well, and a good place that can be useful for it is things like – and this is the one that I hate to say because it'll get people frustrated, but you can actually put a watcher on your Vue router route. So if you want to watch the query string and say, “Okay, anytime that the query string, or this specific value in a query string changes, do something, like update.”
And so that way internally you could have links that click around and update that header, but they're also triggering the thing to update data, to update what have you. And so it's not – Like there are times where it's like, “Okay, yeah that could be a computed value, but I’m actually like I’m wanting to update an input, and that input operates independently of the thing. But if I click on this link over here and I were to land on that page, it would make the input be this. So when I click on that link, I want to update that link or that input,” and stuff like that where there are very interesting use cases for it that may not trigger all of the right bits and pieces. And so sometimes you just have to do something like weird and outside of the loop like that.
[00:26:54] AC: Yeah. I actually had that exact use case recently.
[00:26:57] T: Nice. Why do people find that frustrating?
[00:27:00] AR: The Vue router example specifically is a controversial one because Vue router comes with built-in methods for your component. You have before route update, before enter route, I think or before update route, before enter route and before exit route I think are the component ones. So they're added life cycle hooks to your components that you can listen for. And they work most of the time, but not always. I know in – I think in Chris Fritz, he has his Vue enterprise boilerplate. And with the way that he's set that one up, the Vue router hooks do not work inside of components. By some magic and trickery he has done that, but he's also made it so that if you're going to do something like that, you define it on the route itself. So you're not missing them, but rather than being able to trigger that anywhere in your stack, he's really making you focus and be like, “No. Really trigger this only at the page level.” Like if you need to do something, trigger it at the page level. Don't expect these to work anywhere. Like I have a button component and I want to like block being able to load the page because my button narrowed out. No. Don't do that. It should be at the page level where you're messing with that stuff. And so he made a very specific choice to make that happen.
[00:28:40] AC: And I mean there's also the fact that those are all before something happens and a lot of times you want to trigger it after something happens.
[00:28:49] AR: Yeah. Yeah, that too.
[00:28:51] T: Nice. Now I’m thinking about the page level and I’m like, “Oh my God! If I wanted to do that, could I combine it with suspense? Is suspense going to be ready? I don't know.”
[00:29:05] AC: So the example that I recently had to implement was I decided to go with menu style navigation to allow the user to navigate between different reports so that all uses the same component to render it. But depending on the route, it will ask for different data. So basically I just have a watcher on the route and when it updates I go grab the new reports to display. It's a little heavy-handed. So what I do is like as soon as I see that it changes I do a loading animation. And then once I actually have the data, then I take away the loading animation. Because otherwise it would just be like stalling there for a second and you're like, “Did I actually change it? I don't know.”
[00:29:51] T: Whether good or bad.
[00:29:53] AR: I genuinely don't know. So I don't have a good answer for that unfortunately.
[00:29:59] T: It’s refreshing to hear. Go ahead.
[00:30:02] AC: Just off the top of my head I would say that the ability to stop watching something could absolutely be used for a performance advantage if you're watching something that could be producing heavy side effects and you actually no longer need those side effects. If it's still trying to perform them when they're no longer useful, being able to stop that is honestly huge.
[00:30:23] AR: Yeah.
[00:30:24] T: I will say I’ve had a handful of times where like one of those things that you think you only need for a coding challenge, like a function that runs twice. But then it turns out like every once in a while I do need that and it would be great if I could watch something like twice and then be like, “I’m good now.” I mean I know we can do that now, but like to have it even more streamlined.
[00:30:45] AR: Yeah. We recently made a search component at work and it was like the mental hoops I had to go through because we were doing – It's a debounced thing. So as you type it is going to wait until you're done typing for a certain amount of time and then it will trigger the search. So I need to be able to track a debounced function. But also if you start typing and then click the clear button, I need to be able to cancel that debounced function. Like it was this whole weird set of things, and like trying to do that there was a lot of like really weird, complicated gymnastics that I had to do there. So being able to like do this function. No way. Don't do that function is great. That's fantastic. And so being able to have that with a watcher too is being able to go like, “Watch this for a little bit. Okay, now you're done.” And the fact that you can call that from within the watcher. So once you reach a certain point, you can say, “Okay, stop watching this from within the watcher.” Like if you get to this state, just stop. Don't try to do anything anymore is also super powerful.
[00:31:57] AC: I had a technical interview where they asked me why I didn't use a debounce search on the take-home as if that was a reasonable thing to do in that amount of time.
[00:32:08] T: Yeah, I had one where I didn't have to use a debounce search, but I ended up rewriting one because I really wanted to have a debounce search but you weren't allowed to import any other packages. Yeah.
[00:32:21] AC: How did that go?
[00:32:23] T: It went – I mean I passed. Yeah, I feel like clear is another one of those things where it seems so deceptively simple, but especially depending on like maybe the component you're using, it can end up with so many edge cases that you're not expecting. Like I remember I worked on one where they had hard-coded expectations for what to show when the search is empty, but like the component library that we were using, like the starting empty state and the cleared empty state were different types. Like one was undefined and one was null or something or empty string. It was great.
[00:32:59] AR: I’m making a face right now because –
[00:33:02] AC: Yeah, we're all making faces at that.
[00:33:04] AR: There’s a lot of hands on foreheads.
[00:33:07] AC: Be consistent. That's all we're saying. So I guess I could see a very niche use case where you would actually want those to be different. But if it's – Yeah, no. For wide use, don't do that.
[00:33:22] T: Yeah, it was it was tough for a validation I think mostly. If I were to put you on the spot at this moment hypothetically and ask you to come up with a weird metaphor for watch and watchEffect, what would it be?
[00:33:38] AR: Watch and watchEffect, the metaphor. Watch and watchEffect are similar to the person sitting at the top of the mast on a ship looking for land, right? They have a perspective. They can see things further away, right? So their state is constantly updating. Their state though technically doesn't change, right? There's nothing but water. There's nothing but water. There's nothing but water, right? So they always sort of have the same state until they see something. When they see something, they say something.
[00:34:24] T: They say something?
[00:34:26] AR: No. No. This is like setting a value on a reactive property, right? Their state has updated because they have seen something and they shout, “Land ho!” Like that's what they do, “Land ho!” And so the people on the deck are watching that person up top who's looking for land and they're watching and they are waiting, and that's what watch and watchEffect are, right? They're going to be sitting there and they have other jobs to do when there's land, right? They may just be chilling out waiting for something to happen and suddenly there's land. So now they need to go and like start getting ready to like deal with the anchor or steer away from it or steer towards it. Like who knows, right? Like things start happening that are unrelated to that bit of state. So that's sort of what watch and watchEffect are, right? You are triggering other actions not related to the actual state of things
[00:35:35] AC: I feel like there's a really amazing Titanic metaphor hidden somewhere in there, but yeah, I don't have it like off the bat. I feel like somehow we could use Titanic to make the difference between watch and watchEffect, but –
[00:35:52] AR: I’m going to let you and your listeners judge me really hard. I have never seen Titanic.
[00:35:58] AC: Okay, but you know the story, right?
[00:36:02] AR: Yeah, like they all live happily ever after, right? Like that's how that one ends. That's what I’ve heard.
[00:36:07] AC: They all lived happily ever after.
[00:36:10] AR: That is how that works in my happy little universe.
[00:36:15] AC: Okay. So if people want to find you on the Internet, Alex, where can they find you?
[00:36:21] AR: My blog is at alex.party, and you can find me pretty much anywhere else on the Internet, Twitter, GitHub, CodePen @fimion. I’m that on Twitter, CodePen, GitHub, you name it. That's probably me.
[00:36:40] AC: All right let's move on to picks. Tessa, you're up.
[00:36:44] T: Yeah. This is actually one I thought of last time and then when it came time to share picks, I forgot. But there's like –
[00:36:51] AC: I do that all the time.
[00:36:54] T: Right? I’m among the greats I guess.
[00:36:58] AC: We’ll go with that.
[00:37:00] T: So there's this pretty awesome talk that came out a few years ago called Being Glue by Tanya Reilly over at Squarespace. I feel like it's kind of considered a classic. Basically it's about all the work of being an engineer that's not writing out the code, which there is a lot of work, but it's not always recognized. It's not always recognized fairly and it's not always recognized to the same amount across different demographics. So it's a pretty interesting, somewhat depressing, somewhat encouraging talk, and I’ll link both the recording and the slides so you can check out whichever method you prefer.
[00:37:45] AC: Okay, yeah that is a great talk. It was one of those that I’d always heard about and then when I finally watched I was like, “Oh, yep. I get it now.”
[00:37:53] T: Yeah. I remember when it was just slides floating around LinkedIn and then when the first video came out and I was like, “Ahhh!” Yeah.
[00:38:01] AC: All right. Alex, do you have any picks for us today?
[00:38:03] AR: Yeah. So I have three. First one is Among Us is a video game where you're all happy crewmates and you're all working together and there are no imposters cause you're all working together to achieve tasks but people just keep on mysteriously dying around you.
[00:38:27] T: But the ship doesn't break in half and sink after it hits an iceberg.
[00:38:30] AC: That is true. That is true. And I think it's been sort of very popular lately and so me and my friends have been playing that a lot and it's lots of fun if you haven't played it before. It's worth it to jump in with some of your friends. You'll hate them forever afterwards and it'll be great.
Another one that I have is Hades. It's another video game. If you like Diablo II where you run around and like smash things, but you also like rogue-like games where like you descend into the dungeon every single time and it changes every single time, Hades is a beautiful balance of challenge and story and randomness. And so it's always new. It's always different every single time and it's really fantastic. You are the son of Hades and you are attempting to escape the underworld to find your mother.
[00:39:29] T: And for our listeners who can't see, Ari’s ears perked up at the sound of Diablo II. And the mysterious bee is probably sneezing over where they are.
[00:39:39] AR: And then my last pick is a TV show from the U.K. called Task Master where it is a group of comedians are told by the taskmaster various tasks that they have to accomplish and then they all compete at who did the task the best. And they have been putting episodes of this officially, like official episodes of it on YouTube and it is a delight and it's just a lot of fun. And I’ve recently tricked my wife into also watching it with me. So we're having fun watching that.
[00:40:21] AC: I guess that means it's time for my picks. So loyal listeners will know that I have been out for the last two weeks because I had surgery, which meant I had tons of binge watching time. So my two biggest binge watching takeaways were Crazy Ex-Girlfriend and actually both of these. I’m really late to the party. But yeah, Crazy Ex-Girlfriend was so much funnier than I thought it was going be even though like tons of people had told me I should watch it. I don't listen to people. Come on. But listen to me when I tell you to watch it. It is definitely not safe for work. It's a bit raunchy, but I thoroughly enjoy that especially when it's raunchy from a female perspective. I don't know why. It's way funnier that way. But my second pick is much more wholesome, The Great British Baking Show. I will say if you are really hungry and you don't have food in your house, do not watch. But if you have food in your house, go ahead and watch. It's wholesome. Everyone is so supportive of each other. And now I have this really long mental list of all these exotic desserts I want to try, but I just need to find someone to bake them for me. So if anyone wants to bake things for me, you can hit me up at gloomyloomy and I will send you my mailing information. Just kidding. I probably will never do that. Sorry.
All right. And I suppose with that, that is it for this episode. Thank you for listening, and until next time. Enjoy the Vue.