Exploring Reactivity in JavaScript Frameworks - RRU 243 - podcast episode cover

Exploring Reactivity in JavaScript Frameworks - RRU 243

Jan 10, 202442 min
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

In today's episode, the panel of experts delves into the intricate world of reactivity in JavaScript frameworks. They explore Angular's signal-based approach, React's virtual DOM and hoisting, and how libraries like RxJS and Redux handle reactivity. They also discuss the absence of a universal standard for reactivity in JavaScript and the challenges it presents for developers. Join them as they unravel the complexities of reactivity and its impact on modern application development.
Sponsors
Social MediaUnvoidLucas PaganiniChris FrewinPeter Osah

Advertising Inquiries: https://redcircle.com/brands

Privacy & Opt-Out: https://redcircle.com/privacy

Become a supporter of this podcast: https://www.spreaker.com/podcast/react-round-up--6102072/support.

Transcript

Hello everyone, Welcome to React Roundup and I hope you have a very nice new year. This is the podcast where we keep you updated on all things React related. This show is sponsored by Raygun and produced by two companies, Top and Doves and Onvoid. Top and Doves is very great Top and Doves to get top and pay and recognition while working on interesting problems and making meaningful community contributions. An Onvoid which offers remote design and software development services on a

task basis, so clients only pay when tests are delivered and approved. In today's episode, we will talk about reactivity on JavaScript frameworks. So how are the other frameworks and also React, how are all the other popular frameworks dealing with reactivity on the front end. My name is Lucas Paganini. I'm your host in the podcast, and joining me in today's episode are the hosts Chris

Ruin, Hi guys, and Peter Osa. Hello everyone. All right, so I can bring to the table a bit about how Angler is writing that wave of reactivity, especially now with signals. And I think this has been a conversion that like it seems that all frameworks are conversion into some sort of signal based approach. We saw that I believe first in solid but then we started seeing it popping up in every other place. It was kind of like

when every social media started copying snapshat. So that's basically that's basically it. But yeah, let's of course start with react. How do we currently deal

with reactivity? What is like the signal based approach and react? Peter, Okay, yeah, for react to what I think React uses the virtual dome and then hoisting, right, So, I don't know if a lot of us not about hoisting, right why javascate thinks the jazzkip concept where you can actually have access to a setting vailable outside the functional scope, like right, so we'll I think, so we act kind of works with that in its like maybe when you talk about your states, why U states is actually maybe

a specific to a component we recall it this is hoisting and they a set to once evalues change and to get to us the virtual dome and that's what you So I think that's kind of like a of a view. I think that's just the point of I think that's what the direction I see reactivity in reactas technically, So yeah, that that's definitely the the status quo, right, now, have have you seen people doing reactivity and React in different forms?

For example, our xgs is very popular in other frameworks to do with reactivity because it exposes an observable class in which you can subscribe to and listen to events that are emitted and et cetera. And it also does deals really well with asynchronous events. So our xgs is like a very powerful library for a lot of frameworks to do with reactivity. I know, Angler, for example, for a very long time, relied solely on our experience for its

reactivity. Now it also has some native ways to do it, which is signals, But up until then, reactivity was just our extra ass So have you guys noticed people dealing with reactivity in other ways within React applications besides just the regular hooks? Yeah, so yeah, I've seen that as well. So I've seen I've seen people arectually using ours itself for reactivity and React as

well. I think I've worked on cold business like that too, where we take advantage of the observa paton and then you're listening to events, and you're listening to events and then won't say an event is figured then you can do something. But I think that's the only one I can think of that I have seen of Chase, What have you seen any like anyone you've kind of come across. Yeah, I'm trying to think you guys will probably know it's

not coming to my head right now. There's also for reducks, there's a library that helps you do ACYNC stuff. What is do you guys know what that that library is called? But they that's that's sunk saga. Yeah, yeah, yeah, yeah yeah. So I guess that might be a way of of kind of handling and kind of like pipelining acinc operations. I never got into it because I I know people say, like, once you get

it, it's really awesome, but I could never. I just couldn't get into like the yield and the you need like these special functions and all this stuff. So I'm I'm still uh happily living in hook like use effect land for my side effects. I have seen our xjs as well, like like Peter said, Otherwise, I don't, I don't know, I don't. I can't think of anything else I've seen. Yeah, I think even Jes

with Dogs, I think they kind of use that subscriber paton idea. What you're dispatching on the event and then you're listening to the event as well. I think that's dominantly the patterns of seen and react being used mostly like it's mostly dogs. If not our ages, then there has to be like you state or something. Yeah, so what do you think look as like if you come across anyone too as well, maybe anyone different from these these types.

I was actually hoping that you guys would know because I've never seen, but I really wanted to figure out if there are people doing it differently. But I guess that's kind of a good thing, right, Like the way that people are dealing with reactctivity and react as very standardized, So that's actually good, like boring is good. If everyone was doing it differently, then it would be way harder for us to navigate between one project and the other.

So yeah, let's go through some of the other frameworks then and talk about how they are dealing with reactivity. And by the way, we at no point we defined clearly what is reactivity, right, we just assume that the audience would know it, but just so that we are complete into what we are discussing. So reactivity is you being able to rerender or I would

say, just rerender is really it's anything. It's basically like instead of you having to imperatively tell a variable that is like, oh man, I can't think of a good example. Jesus that my explanation is terrible. Let's go through one very simple example. Let's say you have a variable called full name

and that is computed based on the first name and the last name. So every time you change the first name or the last name, you have to recompute the full name variable, and that can lead to issues if you suddenly change the first name or the last name, but then you forget to update the full name variable. With reactivity, you wouldn't have those problems. You also wouldn't have some other problems with regards to rendering that information for the user.

But at the core, you can tell that a particular particular variable can be listened to, and that means that you can trigger something. You can have a callback, for example, to run every time that value changes, and that way you can solve this problem by listening to changes in the first name and the last name variables and then recomputing the full name when those changes, So that way you don't have to every time you change first name,

remember to change the last name. Just by changing the first name, it will automatically trigger a change and trigger the callbacks that you registered and recompute the full name variable accordingly. So that's just one simple example. But this problem is just really nasty, Like we are probably not familiar with how painful it was because it's been so long that I've been doing everything reactively, but like six years ago, I remember doing a lot of imperative code and it was

just so annoying. For example, a lot of bugs that were like, oh, you updated a variable before, got to update in this other place, and I was like, jah, this is so stupid, like stupid issues, small issues across the code base, and all of that can be fixed with reactivity. But the thing is, there's no universal standard to reactivity in JavaScript, and I mean JavaScript itself, because some other languages do have

natives for reactivity, but JavaScript doesn't. There's a proposal to add observables to JavaScript, but other than that, which wasn't implemented yet, there's no native way in JavaScript to define how everyone should do with reactivity. It's kind of like how the world was before promises were standardized, so you had libraries and mental promises, and then you had other libraries implementing other solutions to deal with

a synchronous responses. And this is what we're talking about. Like every framework brought up its own solution, and we don't know yet which one's going to be the winner. So probably in three years or so, we're gonna have some native implementation and then every framework is gonna say, okay, now we're just going to use the native implementation. But until then everyone's doing it differently.

So yep, now we have proper introduction. Yeah, exactly. So I think maybe maybe maybe I could add in something to reactivity, right, so I think those three reactivity I was trying to sink up the so we're key for example, and made it change. Maybe I have available where I needed something maybe like PETA, and then i'd said to just move it up to lucas I want the reference of that vailable to kind of have to sync with the with the update, with the recent update I need. But so

all the activity does does is to ensure that happens. Quite so it does it your the other Okay, maybe for example, I make a change to this vailable and then it could probably use the call back or listening to that change, and then on listening to the change, its kind of reflects to all lot of instances of that vailable all it could what million many many frame of do we render the whole right course, and render to the dumb and just make it to those just like more likely a very gigantic reload, so

that everything that's updated rights. That's so I think that just how you can see it. Just to sink updates with those sinking data updates, we ensured that Okay, whatever change you make in a new whatever new change changes you make to always going to be reflected in wherever it's devailable or self reference,

right, So I think that's just it occurse. Do you have anything to add to Yeah, I think it also comes down to I mean Lucas mentioned how a lot of frameworks are kind of going to this pattern, and it comes down to this concept of what's declarative and what's imperative. Right, So there's there's a nice link a link at the end of the show. But like Facebook was talking about why they kind of went to this reactive pattern. Anyway, like Lucas mentioned, like imagine, okay, maybe for just a

full name and you have to add the last name. Okay, that works fine. If you have to put an if statement and like hard code it like is this different than I change it? But as soon as you have like five ten, you know, any modern application with hundreds of things that can potentially change, and each of those things maybe change only one or two of the other state variables, it becomes I mean, imperative programming is kind

of out of the question, at least on the front end. So I think all that all these frameworks you know, over time of recognized this and and that's kind of the pattern. It's it's that they're all moving to. So yeah, I guess that's that's all I have. Yeah, okay, so beyond the introduction, all right, so let's go through how those other frameworks are dealing with that. So I can bring a bit about how Angler

is dealing with that. I mentioned it a couple of times, but I'm really curious to know what you guys know about how other frameworks are are dealing with that. Like I kind of know from theory how Solid deals with that, But I gotta say, like I never really built anything with Solid,

like for real, so you can't really speak much about it. But which frameworks did you guys experience and you can talk about how they're dealing with reactivities Peter, Okay, Yeah, So I think for reactivity, one that I kind of know about this React, and I think I've worked with that of View. I think the difference is that for view view users and what call foxy objects, and I think object is kind of like a new concept, right, where with a foxy object you can kind of set or get some

variable. So I think View kind of combined media reactivity with frozy objects. So most of the time when you're doing reactive states with View, you're kind of using like ay object reference, right, So once it changes, then it's not rigas it changed to the original object you wanted to change. Yeah, I think that's how it works for for View. Then React, I think reacts on this kind of you're used hoisting with the virtud and constant revend.

That's still kind of events based, right, doing with events I made this change, and then it's with twigger, so it's listed, there's some I'm listening to the changes made to the state and then courses everywhere in the Yeah, I think apart from that, then with signals yeah, I don't really have like a very good grasp SIG and like you said, I'm just on the same boat as we have. It's still right, it's just it's

knowledge. But then I think Angla spe is kind of quite you have before we active signals, but I'm still I'm still not I've still not gotten them of it yet. But then I think for ALEXJX, because I've kind of worked with more with Angler, good business use that uses the lexs button.

Yeah, I think that is still events based. While you're listening to an event and then you're listening to changes on the veable and once that happens, she just broadcasting to other instances our name updates, right, So I think that's technically the ones I've worked with all CRIZ. Do you have an idea of any one like any how do you work with your activity kind of? Yeah, I can talk about what I mentioned briefly as we were talking before

the show. I was looking into these this concept of ruins in spelt, so they also have kind of moved or or added rather thinking spelt three or whatever version they're on now. They have just here this like their their way of lettings. Felt know that it's a reactive variable is this dollar signed state? So to me, it's basically like a stealing used state. Uh,

and it's ironic. It's exactly what I was just talking about that. I promise I didn't read this before the before what I was saying before about like complex apps, because they say, like, okay, at first glance, I'm reading directly from their documentations, is this this move looks like a step back. Shouldn't we just use let count and automatically make it reactive? And they say, well, no, the reality is that applications grow in complexity,

figuring out which values are reactive and which aren't can get tricky. So they now have moved where they want you to specifically state this case is count. Yeah, that count is with this dollar sign state, and we want that to be reactive in our in our component. So yeah, that's that's all I have. I too, like you guys, I'm guilty of only knowing React here on the React podcast, so I don't have much experience with

with with many other front end frameworks. I think one thing that you touched that is kind of important is this convention about using a dollar sign as a post fix on reactive values. It's not enforced everywhere, but I've seen a lot of different frameworks having developers adopting this convention, and I think it really

helps to make it clear that the variable is indeed reactive. So yeah, an angular this hasn't catched yet, just because it already catched for observables, like we always in Angler, we got used to using dollar sign at the end for observables, but now that we also have signals, we don't want to use it for signals because people are gonna think that it's unobservable. Like

they're both reactive, but they need to be consumed in different ways. So with Angler, people are not adding a dollar sign at the end, but they it's still not a problem because we have to call the value like a signal in Angler is a function, you literally call it, so you have, for example, first name, you would have first name open and closed

parentheses. You're actually calling the variable and that returns its value. And it also creates a connection between the thing that is rendering it and the signal itself. So every time that the signal changes, Angler already knows that it needs to re render that particular part of the UI or even the within the typescript code itself. If you have if you call it the computed, Angler has

a computed function, and then this computed function takes a callback. So imagine that you write computed and then you call it, and you pass a callback. Within this callback, you can just use signals as normal, and Angler will automatically understand that this function depends on those signals, so when they change,

that function will automatically be triggered. So it's it's very smart, which is a bit different from the explicitliness of React effects, where you need to explicitly say like hey, rerendous effect when and those values change, you know, kind of like they are keys and if the key change, then you

rerun this. Angular does that automatically, So I think that solves a lot of issues because with React we can just forget to add I've seen like nasty bugs that took me out why to figure out what it was, and it was just a person forgot to add a variable into the effects array of dependencies.

So it's really nice that we don't have this problem with Angler. Some people complain it at the beginning because they were accustomed to how React does it, and they were like, oh yeah, but you're not being explicit like this is a bit too magical, but it should be. A framework should provide some level of magic. Otherwise, why are you using it if you're going to type a lot of boilerplate all the time. So yeah, that's

basically how this is being handled on Angular. On the Angular side, I do really like another convention which is used as a prefix, so React standardize that with hooks, so every time a declatter hook is like use something. And I'm trying to push this convention for Angular too, because Angular also has this concept of functions that can be injected, because you can just use the inject function internally within the function. And then that creates a problem because just

to give you a bit of context without it is becoming super complex. The inject function in Angular can only be called if you are at a component constructor or, like it can only be called within an injection context. But to explain what it's an action context would be too complex. So let's just imagine

that you can only call it in the component constructor. Okay, so you can only call it when the component's being constructed, all right, So what the problem is if you call a function that internally call this cause this inject function, and you don't know that this function calls the inject function internally, then you don't know that you can only call it in the constructor and you might call it at a later point at which it will not have the injection

context, and then it's going to fail. So what I'm trying to push forward as a convention is to always perfect those functions with use, and then if the function starts with use, you already know that you can only use it if you are within an injection context. Otherwise it's just going to fail. So those two conventions are really helpful. Dollar sign at the end and

the use prefix. Yeah, I think I think you bring up a good point there with I think even with these kind of these whatever you want to call it magic or syntactic sugar, even with reactivity, you're always i mean, we're always doing this as software engineers, but you're always fighting against complexity. You mentioned you've you've seen some nasty bugs, and I've also seen some

as well. And also just the hooks themselves can get really nasty and messy, right because uh, you know, you have maybe have dozens of dependencies and and maybe one is not even used, So I think, I think what is still important probably regardless of framework, but I know it's something React pushes is like your own how you compose the hooks themselves. So and I've I've been guilty of that. I've looked at some of my hooks and oh, okay, actually, you know these, I'm kind of mixing, you

know, I'm mixing reactivity again. It's this kind of disadvantage that React is disadvantage and advantage that reacts so easy to write. Sometimes you end up just quickly putting together hook and you get way too many dependencies or whatever. But if you take a step back and you look at, you know, the composition of your hooks, because this is probably more React advice, but there's

probably simplifications that you can make. But but you talking about these these things in Angular, it makes me wonder if now there will be like almost like a third generation in React. So like going from you know, we had the class components that may have hooks, I wonder if or maybe you know,

maybe it is by design they should be explicit. But I wouldn't be surprised that there's some sort of other abstraction layer where somehow you know it would save so many beginners from you know, we all have seen that infinite rendering thing right where it's just as simple as leaving out that array and then you're just you're just infinitely rending your components. Wow, what's going on? So I wonder if if there's something on the horizon would be quite interesting. Yeah,

I just just wanted to add that in. I don't know, I don't know else where we want to go from there. I don't know if if you had some comments too, yeah, like yeah, I agree with so they just they need to be a way for you to actuably know what's like since yeah, since the activity looks like magic a lot, like we

need to know how to kind of differentiate this reactively well this job. So I've worked a lot of clothes and so many kind of boiler plates and confusing coulde yeah most of the time get that A lot of many could business where it kind of confused, how like especially in Angola, Like I think look as get the example way I've actually seen they coulde biz were by observable, not even with dollar. So I'm just litally and confusion like whoa, I

know this? Like whoa? And yeah, so I think the conversion is very important. Just to know how like what it is, right, is kind of very important for identification, right, And yeah, I think over all, yeah, I think that's actually very important. And I think one thing we need to know about the activity is that for for us, so

I kind of actually work to work with reactivity better. I feel we need to know the underlying principle behind reactivity in any framework were using, right, So that why most of the time I usually try to just look at their

underline principle. Okay, yeah, I know for react or is it working with one javasket, I concept that maybe something new, Okay, Like I gave an illustration in the beginning for view whereby we use it use kind of the objects and kind of using for your objects and then kind of brigging like an observer pattern with it. Kind of I think signals work with that with that similarly as well, I think it's kind of signals to us in signal.

But I've not really kind of like extensively read about it. Kind I don't really have more, but I think it's very much important, even for for React. For React there's on every form of jask developer, so those know the principle of reactivity in those frameworks. For example, you give an example of use effect and then I think I think the mother moth the reacting gave is setting. I think they adopted a post on the right like why

we shouldn't be kind of used environing might not need a use effect. I think I would the link on the I think I adopted on the chat right, so you might not need a use effect for certain things we are trying to kind of use the effects and then adding some dependency are just some values in the dependency. So I think one thing we need to do this the underline principle of reactivity of those frameworks and how to use the kind of I

think that's kind of very important. So Chris, what do you think that like maybe piece for or issues that a lot of people face, we're using the activity maybe a sespecially in React you work with as well. Yeah, I think it comes with with those kind of special magic. I mean usually with magic you pay for for special rules. So I know React, I'm

sure it's still somewhere in their docks. They have like that rules of Hooks page, right, So I mean you you get huge advantages, but there's stuff you just can't do like you can't put a hook within a hook. That's like one rule. And also that what what you were mentioning, Peter is what came to mind is also how you update even just a simple state

variable with in React. Right, so you're I'm sure it's similar in most frameworks, but in React you you typically want a fresh object, right, You're not supposed to mutate, you're not supposed to append directly do an array for example. The fix is easy, right you You you create a new

ray and a new array as you said the state. So yeah, small things like that, but it's a really good point that you need to whatever framework it is, and unfortunately they're usually framework specific, but you should know those those details to avoid confusing, confusing bugs. And that's probably like what Lucas mentioned in in Angular apparently this inject Unfortunately I can't speak much more to it, but it seems like that's rue, like you can only use certain

things in certain context. So yeah, that's what that's as well. So look as speaking of like, I think I like a general like also as a confusional, I think it's more like a debits because I've had I kind of have digital love they look like this before, like the aspect of do you think I think it's based on the activity as well? Do you think

set state or you STI it is synchrons or synchronos. Yeah, Like the answer for that, like because I kind of get that a lot on reactivity, I think so many people argue that because of the way you stick to work. So it's React, it's kind of synchrons some seats. So what do you think, like from working with React at least? Yeah, Yeah, first, like that's that's a really good question, and this is not even just specific to React, like other frameworks also also get into this debate.

And basically the thing here is, at one point, you when you think of code being synchronous, you think that like you call it, you call the function, and everything that you're doing right now just stops, and then it goes round that function and Danny comes back and runs the rest of your cup. That's what we generally think about when we say the code is

synchronous. But the thing is when we're talking about reactivity, then people started giving different meanings to sink and a sync because you can technically have a synchronous refresh or an asynchronous refresh, and if you think too much about it, you're just gonna go mad because it doesn't really make that much sense, Like if you stop to think about it, like everything that you're executing is going to be executed and this other thing that you called is only going to be

executed afterwards. So that's kind of like the definition of asynchronous, right, So why are we debating if it is synchronous or not? But the question I think is less about it being synchronous or not, but more about at which point does the JavaScript run time decides to execute that callback, because there are many things that happen within those idle moments in which your code is quote unquote not running. Like there's always something running, right, the browser is

running, even if your code itself is not running. There are a lot of listeners, there are a lot of other stuff going on. The user is scrolling through the application, so something is clearly running, but your code is not running anymore. So what's going on is that the browser has stages and basically like it's going to execute your code, and while it is synchronously

executing your code, it can't repaint the page. But once your code stops, then it will repaint the page, it will refresh, and then it will it might like trigger another code that you have, like maybe it's going to trigger an event you have, or you are listening to request animation frames

something like that. Now, when we talk about hooks being synchronous or not, this is what we're referring to. It's like, okay, of course, when you call set value, when you call set state, the rest of your component render code is going to finish running before React rerenders or retriggers your component with new with the new value. But when is React going to

trigger this rerender? That's the question. And what a lot of people are calling synchronous is when the code is re rendered before the browser actually has a chance to render. So it's kind of like the framework triggers this recalculate of the UI before the browser has time to really render the UI, and that's kind of like being called as synchronous. And when it waits for the next tech or the next I don't know if sick is the right technical way to

call it, but there is like the right name to call. The next time that the brother is going to do something, then we're calling it asynchronous, which is what our XGS by default does, but you can also configure our XGS to run in an immediate way. So yeah, all the context to say, I think there are both a synchronous ways, and we just need to stop calling it sync because it's just super confusing to everyone. So

we should just make it clear that it is asynchronous. But uh, it hyder happens at this point of the browser event or it happens at this other point, so we've got to figure out another way to refer to that.

Yeah, my only comment there, I think I would have to look into the at least from React, like the use state it's super I mean you have to like at this end of the day, it's JavaScript is single threaded, right, so I think even yeah, looking into the source code of youse state, you would assume there's like some sort of queue, but yeah, like you said, like you know, there could be other things going

on. And then it really comes down to probably not even React or any framework, but like what what the the JavaScript engine wants to do, right, and what thinks is most efficient? Right? I mean yeah, so yeah, you're probably right. You know, you can there's probably tricks where or there's there's ways you can force things or try to get them to be

as sync or as ACYNC as possible. But at the end of the day, I think if you if you really get into complexity, you're kind of victim to Yeah, just the the JavaScript engine OPTI trying to optimize as best it can. Not to speak about web workers or things like that, but that's what we can do for another episode. Okay, I think that was enough talk about reactivity, So let's start wrapping up, unless Chris, if

you have anything you'd like to mention before we start wrapping up. No, okay, all right, so before we we officially stop, let's do quick promos. So I'm just gonna plug on Void. So, as I as mentioned in the beginning, on Void is a design and software company. You can hire andvoid professionals to work for a company remotely. And the interesting thing about on avoid in comparison to other companies that provide the same services, is that you have the option to hire on a task based manner. So what

the means is you only pay when tasks are delivered. Sure, that's you've seen that thus far, but only when they are delivered and approved. So if they are delivered but they're not up to the standards of your company. Then you can just keep requesting changes until it is up to your standards,

and you're only going to pay once you really approve it. So that's a major differentiator, and it makes companies much safer to outsource their parts of their design and development teams, knowing that they're not going to lose any equality by doing so. So yeah, if you're interested on that is you and vo Id dot Comcovoid dot com. So yeah, how about you, Chris. I think I'm just gonna promo the link I mentioned to this the really nice

presentation by Facebook. It goes into quite a few topics, a little bit what we talked about today on reactivity of course, and also imperative versus declarative, and also into the kind of I think what eventually became reducs, this concept of the flux pattern basically all the problems they ran into with growing complexity in their apps and how they kind of found all these patterns and why they still use them today on the front end. So really really cool video.

They have like three or four different devs talk about, you know, certain parts of what they ran into throughout their projects. Nice. Nice How about you, Peter. Okay, Yeah, so I have like an mdan link of chats right about like hoisting through I think most of them time, I feel on one of the main concept about from how did the reactive how reactive state walks with you have don't kind of works with hoisting right, So I

think it's the concept that's kind of failing. Most people don't have on the build a bit kind of music kind of you don't know like that we use it on this is how it works, and this is how we act kind of work with stags with right kind of So I think I just I will just drope a link on hoisting and then also they see the link of yeah, I dropped earlier, but you might not need music effects, So most of the time we just kind of use the effects for everything we really not

need. Issue I think are the two links I have kind of yeah, okay, and we put them into the comments section, so if you're watching this on YouTube or Facebook linked and then you will be able to see those links in the comment section. If not, they're probably in the show notes. So yeah, okay, I don't think I have anything else to contribute

to this discussion. So guys, thank you so much. It was good for us to have a podcast again because for the last few weeks it was really hard for us to find time, like the end of the year, things like that. So it's good to be back, good to have you guys back. So yeah, happy New Year for everyone, and I'll see you in the next one.

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android