Charles Max Wood (00:01.714)
All right, here we go. Hey, welcome back to another episode of JavaScript Jabber. This week on our panel, we have Dan Shapir.
Dan (00:10.962)
Hi from a really warm and really sunny Tel Aviv, even though I'm feeling a bit under the weather, so I apologize to our audience in advance. I'll try to hold on to the very end, but if I don't, my apologies.
Charles Max Wood (00:25.23)
Charles Max Wood from Top End Devs. Yeah, I hope Dan sticks around. We have a special guest this week and that's Evyatar Alush. Did I say that right?
Evyatar Alush (00:33.871)
Mm-hmm. Yeah, perfect.
Charles Max Wood (00:36.85)
Do you want to introduce yourself real quick, let people know who you are and why you're famous?
Evyatar Alush (00:42.118)
Uh, yeah, sure. Hi everybody. I'm Avatar. I'm super happy to be here. Um, I'm an engineer here at MetaIntel VIV, also Tel VIV. Um, I'm passionate about open source development, developer tooling, API design, and I work on a bunch of open source projects like VEST, the Validations Framework and a few others as well. Also, I'm also a public speaker. I speak at different conferences all over the world. Um, and again, super awesome to be here.
Charles Max Wood (01:13.276)
Nice.
Dan (01:13.426)
Yeah, I have to say that I recently, relatively recently, met Wiatar at the React Next conference, where we happened to speak one versus the other. So I couldn't actually attend his talk because I was busy giving mine at the same time, but I did watch the video of his talk afterwards. It's highly recommended. I think you spoke about implementing your own context library or implementation.
for React, right? Like how context actually works on the inside, kind of.
Evyatar Alush (01:48.878)
Yes, so it was almost not for React, but for general use JavaScript. So if you could take the concepts and ideas for the React context and use it outside of React, because if you have a function that calls a function that calls a function, and you don't want to drill all the arguments all the way down, how you could implement that with vanilla JavaScript without using React at all?
Dan (02:14.378)
Yeah, I thought that it was really cool. It's kind of like a segmented global or something like that, right? It's like a global where you only see that part that you're interested in and not like exposed to everything.
Evyatar Alush (02:25.674)
Yeah, exactly. Only that you do not pollute the global scope. It's all within a single closure that only you have access to within the current call stack. So that's the cool idea.
Dan (02:38.459)
Cool.
Charles Max Wood (02:43.41)
Very cool. So I guess we're gonna be talking about Vest today. I have to say that I've kind of looked through some of the docs on here and it looks cool, but do you wanna kind of give people a top level idea of what it is and what problems it solves for people and then we can dive into how it works?
Evyatar Alush (02:50.909)
Mm-hmm.
Evyatar Alush (03:05.802)
Yeah, definitely. So Vest is a form validation framework. Not very unlike, not much unlike many of the others frameworks you've used, only that it adopts the syntax and style of unit testing libraries like Mocha or Jest, hence the name Vest. And the concept is that you can describe your form and form validations as a suite of tests and each of the tests gets its own field or sorry, each of the field, each of the fields gets its own test.
or you can have multiple tasks for a single field. And this way it makes it very easy to read, very easy to understand, also very easy to write. And when you come back to maintain it in the future, it's all separated from your feature logic, so it's really also easy to maintain. This is the core concept, but it comes with many, many other utilities and capabilities. It is stateful, so it manages a lot of the
heuristics of validation and many of the difficult parts of validations for you. So this is something we can touch a little later on.
Dan (04:13.166)
To give our listeners an idea of how it looks like, and again obviously that's kind of challenging in a podcast, think about like you said, like a jest or something, but instead of it, you write the word test, otherwise it kind of looks the same, and instead of what's it, expect, you use the word enforce.
to state that you enforce that a particular field meets a particular criteria. And it can be enforce something dot is not blank to indicate that the field must not be blank.
Evyatar Alush (04:52.64)
Exactly.
Dan (04:54.938)
And like you said, it's super familiar and super obvious in terms of the syntax and even semantics for anybody who's familiar with the common testing libraries for JavaScript.
Charles Max Wood (05:11.194)
Yeah, the syntax looked pretty familiar to me. Just getting in and going, oh.
Evyatar Alush (05:18.31)
So the idea is that you can build up on the existing knowledge of the users. So many of the users, especially today, or many of the developers today, already have some experience with unit testing libraries. So it makes very much sense to use that existing knowledge to describe something that, in general, I think is very similar to unit testing.
that is very similar to unit testing because in validation, you basically have a set of criteria that you want your data to pass and this is the same as unit testing and validation. So the idea is to build upon that existing knowledge.
Dan (06:01.174)
So given that AJ isn't here, I'm going to start with a contrarian question to kind of take AJ's place. And my question is this, on the client side, because I assume you can run the validation on both the client side and the server side, but I'm going to start with asking specifically about the client side. On the client side, why do I even need JavaScript-based validation and not just rely on the
Evyatar Alush (06:04.278)
Okay
course.
Dan (06:29.95)
you know, the validation that's built into the HTML, what used to be known as HTML5.
Evyatar Alush (06:37.342)
Yeah, so HTML, especially HTML5, improved a lot in terms of what it allows you to do and in terms of the validation capabilities that you have, but it still lacks in many different areas. And I think this is an argument we've had on Twitter like four years ago, Dan. I don't know if you remember. And you said the same thing.
Dan (07:00.962)
Probably not.
Evyatar Alush (07:03.066)
There was a week when everybody talked about form validation and why people actually need to use form validation libraries when they have the HTML5 validation capabilities. And I think that while very much better than what it used to be in the past, it is still lacking in many areas and we still need to augment the capabilities of the HTML form in order to receive more benefits and more capabilities.
that we do not yet have. For example, when we want to validate fields that depend on different fields, for example, when we want to validate password confirmation, this is something that's very difficult to do with the built-in form validation that we have in HTML and when you want to do something that may show you a validation error, but is not really a validation failure such as password strength.
This is also something that's very difficult to do with native HTML form. And I do not say that this is strictly impossible, but it is something that's more difficult to do. Now, on top of that, there are many stuff that you want to do with your form, like have a special display, and you don't actually want to use the normal or native HTML capabilities just to display the errors. You want to have some other way to manage that. And on top of that all,
If you want to share your validations logic between your server and the client, then it makes a lot of sense to actually have a separate library that manages that for you.
Dan (08:40.186)
Yeah, I think that this is really an important point and probably an obvious one for experienced developers but may not be that obvious for inexperienced developers in that the fact that just you having client side validation is obviously not enough. You have to validate the data on the server side because, you know, who knows what the client might send. You know, you might think it's your web.
Evyatar Alush (08:54.7)
Oh
Dan (09:07.454)
Interface but what in fact it's some bot just doing a form submit an HTTP post even and And you know who knows what and that way? injections go So so yeah, you definitely want to validate your data on the server side before you know putting it in the database or whatever And like you said obviously having the exact same code on both sides makes
of sense because you only need to write it once, ensure that it works once, and obviously, you want to catch exactly the same errors on the client side for quick response, on the server side for actual correctness and security.
Evyatar Alush (09:41.973)
Mm-hmm.
Charles Max Wood (09:52.854)
Yeah, it's interesting talking about it in that sense because in my experience, I'm mostly doing Ruby on the back end and JavaScript on the front end, and so I can't use the same validation on both ends without writing it twice. So I kind of like that it's... How do I put it? It moves between the two pretty easily. You don't have to...
do a whole lot of extra work to use it on the front end and on the back end if they're both JavaScript applications. So that in and of itself lends to some pretty nice reusability.
Dan (10:35.442)
Now, again, a few more questions about how it's used again for our audience. In a regular testing library, you run a test and if a test fails, you basically stop and, you know, output the error or errors and then, you know, fail the test. What is the return value? How do you, like, how do you indicate success versus failure?
I guess you invoke a validation function on passing in the form data in some way. Maybe we can touch about how you pass in the form data as well. But then how do you get the indication of success or failure?
Evyatar Alush (11:05.654)
Mm-hmm.
Evyatar Alush (11:22.166)
Yeah, definitely. So just to clarify, or just to add on top of what you just said, when in a unit testing library, when you fail, you do not just stop, you run all of the tests and then display. Yeah. And this is pretty much the same with Vest also, with just one difference that if you have multiple tests for a single field and the first one fails,
Dan (11:36.447)
Oh yeah, obviously.
Evyatar Alush (11:49.09)
There is no need to continue to the next validations of the same field because the first one already fails. Usually there is no need to run multiple tests if the first one already failed. Now, what you get back once you run your form validation with Vest is just an object, a results object that contains a serialized result of the validation. So it has the list of tests that just passed or failed, or if they have any warnings instead of failures.
It has the groups because you can nest tests within groups and it has all the metrics and statistics that you need in order to infer your result from that. But also it has multiple selector functions. So it has a function called get errors and which it returns you a list of errors, either for the entire suite or for a given field, depending on whether you pass in the field name or not. And like that, it has also a function called is valid and
It returns you a boolean if a given field or the suite itself is valid or not valid. And the same, it gives you a function called has errors and has warnings that works pretty much the same. So it has a bunch of functions that does all the magic for you in terms of understanding the meaning of these values that you get back from the validation result.
Dan (13:11.901)
What's the difference between an error and a warning?
Evyatar Alush (13:15.098)
Oh, okay. I thought you were going to ask what's the difference between error and invalid, which is a bigger difference. Yes. Um, um, because yeah, that's, that's a more interesting one, uh, because apparently having an error does not mean invalid necessarily or not being valid does not mean having errors. So we'll touch on that, I think, uh, later, but in terms of a warning or an error, uh, we need to distinguish between two types of failures.
Dan (13:20.726)
Ah, yeah, okay. I missed that.
Evyatar Alush (13:43.39)
in our validation suite. So a failure normally has an error severity, which means that when it fails, it just prevents form submission. This means we cannot continue. This is a critical failure in our data. But sometimes we have also data or tasks that we may allow to fail, but we do want to indicate something to the user. And the intention behind Vest is to allow you...
as the developer, not to just write your validation logic in one place, but also specify the messages that the user would get in the same place. So when you want to specify a warning test, for example, password strength, when you type in a weak password, the website may allow you to continue and show that and continue with that bad password or weak password, but it does want to show you that. So you can specify a test that is
Charles Max Wood (14:37.51)
Mm-hmm.
Evyatar Alush (14:42.322)
warning only and then Vest takes this test and puts it in a different basket within the results. You may still view it, you may still show it to the user, but it does not set the form validation to invalid. So this is the difference between error and warning in the context of form validation.
Charles Max Wood (15:04.391)
That makes sense.
Dan (15:04.53)
And how about error versus invalid?
Evyatar Alush (15:07.87)
Yes, that's an interesting one, I think. Because for the first three years of VEST, I think, I did not even have a notion of invalid in VEST because I did not have the correct heuristics of how to describe what is valid or what is invalid because I had some mental logic missing in there, but generally, for example, when you take in a form without any data in it,
Dan (15:09.752)
Ahem.
Evyatar Alush (15:37.266)
It's still not valid, so invalid is false, but it has no errors inside. So a form can be without any errors at all, but still be invalid. And this is the main difference. We need to distinguish between these two stages. A form has errors and the form is invalid and best allows you to actually distinguish between the two and adding on top of that, if you want to consider the idea of optional fields, of course.
which is a field that may not even be filled, or it might sometimes even have an error, but still allow the form to continue. Because on some criteria, an option field is allowed to fail. For example, when you have one field that, for example, you have to specify either a password, either an email or a phone number, just as an example, when signing up, you may fail. The email...
Email field may be empty, so it's failing, it has errors inside, but you may still be valid. So this is an example. It's not a warning. Otherwise, if the phone number field was empty, both of them would have failed. But because it's an option, conditionally optional, you may continue.
Dan (16:55.574)
Now, I have a question about that kind of goes to the heart of open source software, I guess. And that's you said you had a certain mental model, that initially the concept of invalid as opposed to error didn't exist. And then at a certain point in time, you realized that you needed to make this distinction, and you introduced it into the library. Was this the result of your own thought
processes and understandings or did one of your, you know, did the library user or users, you know, reach out to you and say, hey, you know, we need to make this kind of a distinction, it's missing and then you thought about it and, you know, oh, no, these guys are actually correct. Or maybe even somebody, you know, forked it and did a PR or something. So how did, you know, what's the process that you, you know, happened to you?
with this library about adding features and capabilities and shifting the mental model.
Evyatar Alush (17:59.998)
Awesome question. Um, this is something, I would say a mixture of all that you just said, uh, without the PR part. Um, basically from the get-go, I knew that I am missing the concepts and the stuff missing to define logically the idea of what an, uh, what a valid or invalid field is, I knew that from the get-go, I knew that valid or sorry,
Invalid does not mean, or sorry, not valid does not mean invalid, but I wasn't able to articulate what valid actually meant, only that not valid is not necessarily invalid. That's I knew. And what I decided to do is to postpone the decision because with my own personal use cases at work, I did not experience the need of implementing is valid yet. And I waited for the community to actually bring up the topic.
And what happened is that over time, when the library grew in popularity, people came with requests that I knew were somehow related to the concept of validity in the world of optional fields, which were also missing in the beginning. We only had errors and warnings. And when they came with a request for specific or specifications of optional fields, and when we would define together both on Discord and on GitHub issues,
the specification for optional fields, only then I was able to build the mental model for validity. So it was all tied together. It was both a personal mental process and a community process.
Dan (19:43.362)
cool.
Charles Max Wood (19:43.79)
Now when you say optional fields, what are you talking about there?
Evyatar Alush (19:44.302)
Mm-hmm.
Evyatar Alush (19:47.826)
Yeah. So in most of the validation libraries and form validation libraries, fields are optional by default and you have to specify that they're required. This goes the other way around, which means all fields, unless specified, are required. All tests have to pass unless you specify that a form or a specific field is not required, because usually when you type in a form,
Charles Max Wood (19:59.804)
Oh, okay.
Evyatar Alush (20:16.842)
You want all the fields to pass, otherwise not. But you have to specifically say that. That's what I see as more natural. And when I specify that a field is optional, by default, an optional field on VEST, because VEST is unaware of your internal business logic, it means that the field did not go through validation. It does not mean that a field is empty. It means that VEST...
did not go through into validating it. And why it happened? Because the user did not type inside of it. The user did not type inside the username, for example. And that means that it never went through any validation process because not on every keystroke you validate all the fields, but sometimes this is not enough, as I mentioned, sometimes you have fields that depend on one another or mutually exclusive fields. So sometimes you have to also tell Vest, Hey,
This field, this email field is only optional and you need to omit it from any result when the other field is already filled, when the other field is already filled up. So for example, you can tell Vest, hey, this password, this email field is optional when the phone number field is filled up. So there are two types of optional fields, either automatically when Vest tries to understand what is optional by
whether it was already typed in by the user or not, or if you tell it, hey this field, you should just omit it and it's optional.
Dan (21:50.215)
Now, you mentioned a couple of minutes ago that the test mechanism is stateful. Can you elaborate on what you mean by that?
Evyatar Alush (22:00.78)
Mm-hmm.
Yes, definitely. So, in order to allow you better ergonomics, or to give you better ergonomics, Vest maintains an internal state of the validation. And what I noticed is that the initial versions of Vest were not stateful, which meant that you typed in a field and Vest would validate one field and then I would have to keep the validation result and the validation errors outside in an external state.
And then when I would type in into a different field, I would have to do it again and save it in React or Vue or Angular or wherever. And what I decided to do in version 3 of Vest... Mm-hmm.
Dan (22:41.806)
Why not question, quick question, why not just revalidate everything? Is it because some of the tests are too expensive?
Evyatar Alush (22:50.242)
Uh, it's not because... sometimes yes, but that's not the reason. And you know the pesky feeling when you type inside one field inside the form and for example, inside the username, suddenly the whole field lights up like it's Christmas? Um, so I was trying to avoid that. Vest allows you to only validate the field the user is currently interacting with. Which means that whenever you type inside a field, you only run the validations for that one. And what happens internally is that when Vest...
And this is in the current versions and the next ones as well. And I'm currently working on a future version of this, major version number five. So inside Vest, when you type inside a field and it validates that field, next time you type inside a different field, it's not going to revalidate that field and it's also not going to omit the previous results. What it's going to do is take in, merge the previous validation results with the next validation results.
what's going on at the moment. And then you're going to both save output and performance. And for the client, maybe it's not very important, but when you run it for on the server, for example, it might be very beneficial or when you have async validations, that's also very beneficial. And that's what, when you get very smooth and very fast and very performant experience and Vest tries to do a lot of the smarts for you.
Evyatar Alush (24:15.819)
Oh, I think you're muted and.
Dan (24:20.022)
Yeah, the dog was barking, so I muted. You kind of segued already into what would have been my next or follow-up question, which is how do you handle asynchronous validation, or can you handle asynchronous validation, which based on your answer, I gather the answer is yes.
Evyatar Alush (24:40.211)
Mm hmm. Yeah. So.
Charles Max Wood (24:41.938)
Can you tell us what you mean by asynchronous validation?
Evyatar Alush (24:49.134)
Okay, I thought it was for Dan. So yeah, when you want to run an asynchronous validation. So for example, when you type in inside a field and you want to get some validation results from an external source, like your server, or from an extensive computation that's done inside of a web worker, for example, you want to run an async validation, one that does not stop the validation from running.
and does not prevent you from getting the immediate result. And what you do to allow that is specify the function, the test function as async or instead return a promise. So pretty much the same thing as you would do in a unit testing libraries, again, trying to build upon and extend on existing knowledge. And if the promise rejects or if the async test throws an error,
then the test is considered to be failing.
Charles Max Wood (25:49.662)
Okay, so I can imagine for example if you have a validation where it's, hey the username has to be unique, right? And so you're validating on the front end, an asynchronous validation would be, I've got to go ask the server if it's in the database already.
Evyatar Alush (25:56.971)
Mm-hmm.
Evyatar Alush (26:05.351)
Exactly.
Dan (26:07.206)
Yeah, you kind of remind me of the time that I proposed to a large company that I worked at that after they changed the password policy yet again that they require that not only that your password will be unique compared to all your previous passwords also that it will be unique compared to the passwords of all other users in the system.
so that your password will not match the password that any of the other users ever had. Ha ha ha.
Charles Max Wood (26:40.031)
I can type the word password with a lot of different lead numbers in them. So, I know.
Dan (26:44.418)
No, obviously I was joking. I mean, I mean, yeah. Yeah, you know, like compare your password to my password to your old password, you know. Obviously that's silly, but be that as it may. Be that as it may. How like, and that kind of also segues into another question that I will have in a bit, but how...
Charles Max Wood (26:54.68)
Right.
Charles Max Wood (26:59.194)
Well, yeah.
Dan (27:13.678)
did you adjust the APIs to be flexible for synchronicity? Like I see that in the test function, again, which correlates to the it in testing libraries, you can pass in an asynchronous function, which kind of indicates that I'm going to do an asynchronous test on that field. But doesn't that also mean that in the return structure,
rather than returning a value, I need to return a promise. So how did you deal with these things where in some cases, things are values and in other cases are promises? I know that there are certain libraries that deal with it by making everything a promise, but that might be too uncomfortable in your scenario because in your scenario,
Most things would be just values rather than promises and forcing everything to be a promise might be like too big a pill to swallow. So how did you deal with that?
Evyatar Alush (28:23.194)
Yeah, exactly. I agree about that being uncomfortable. And this is an interesting question because not only it required an API change, but it also required some internal flexibility of the design and some clever uses of promises and the statefulness of Vest and the way it's done and for the same reasons you said, you want most of the validations to appear on the page immediately.
and only wait for the async stuff. So what you do is when you get the validation results, so you get a validation object, result object directly from vest or when you call the sweet function, you can dangle a done at the end of it, a done call, which is very similar to a then only just to make sure that you don't think it's a thenable. Meaning that it's a promise. It gives you, it allows you to chain a done function. When
And when this function is done running or when the validation is done running, then you can run whatever it is that you want inside of it as well, inside the done callback, which in your scenario would be to update the view or to change the state of your UI.
You're muted again, Dan.
Dan (29:45.83)
Why not make it a Xenable? Is it because it has additional fields that you don't expect to see on a Promise? Why did you introduce that done method as opposed to just using Xen?
Evyatar Alush (29:59.278)
So mostly that because I could extend the promise or I could make it deniable or build my own abstraction of a promise, but I did, I do not know what libraries people use, what interfaces they have, what run times they run. And I did not want to make any mistakes on that area. Now, usually it would have worked, but I've already seen like weird cases when people use the vest.
on a television OS and suddenly stuff started to break. So I wanted to try to extend as little as I could, the native APIs and the built-in functions and try to make it as less customized as possible in terms of extensions.
Dan (30:49.594)
I get what you're saying and obviously you have much more experience with this library than I do. Basically I don't have any experience with it. But my basic instinct would be, if at all possible, to make it thenable. If for no other reason that making it thenable means that you kind of
Dan (31:18.914)
built in JavaScript capabilities and APIs. Like if you're thenable, then await works for you, promise all works for you. There's like a ton of stuff that just works if you're thenable. And by the way, for listeners, just so you know, in case somebody doesn't know, a thenable is simply an object that has a then method. That's it. And oh, and that then method takes a function as an argument.
which is the function that gets executed when the object resolves. And for a lot of JavaScript APIs, you know, where you pass in promises, they don't actually like check that this is really a promise. All that they really look for is a then method. And if it has a then method, then it's good enough for them. And they can deal with your own like...
custom implementation rather than a real quote unquote promise, you know, just if you have the appropriate then method implemented.
Evyatar Alush (32:26.43)
Yeah, so I completely agree with that. And I do love the duck typing area of that. But one more feature that having that done function allowed me to do or to build was conditionals inside of that done function or selectors. So for example, let's say you have 10 different asynchronous fields, like one for the username and one for the password and one for the email.
Dan (32:34.263)
Hmm.
Dan (32:46.391)
Mmm.
Evyatar Alush (32:56.43)
and they all run at the same time because now I'm validating on submit. And I can add another argument before the done callback, which is the field name, the field that I want to run that callback for. And this means that whenever that field is done, do not wait for the others, but whenever that field is done, when their username field is done, run that callback. And I can chain as many done functions as I want.
So I can run one for the username field and one for the password field. And this is not just as a promise shim, but actually a feature that this change allowed me to do.
Dan (33:40.726)
So it's kind of like similar to the RXJS approach. It's chainable, it's quote-unquote asynchronous, but it's not promises.
Charles Max Wood (33:49.094)
Mm-hmm.
Dan (33:55.95)
Cool.
Charles Max Wood (33:58.646)
I have a couple of questions on this as well. One of them is, so sometimes it's, hey, I need the usernames to behave this way, right? And sometimes I have a field in my form that's like, it's just like, I know it's a proper name, like a first name or a last name or a full name, right? And so maybe I'm collecting that over and over and over again, you know, maybe with fields that are called different things. So can I create some kind of modular?
Evyatar Alush (34:08.846)
Mm-hmm.
Charles Max Wood (34:27.142)
validation that I can add to fields? So for example, I know that cities, states, first names, last names all need to be capitalized, right? They're all going to have alphabetical, you know, maybe a period or a dash in them, you know, that kind of a thing. So can I create those and then just say, hey, apply these generic validations to these specific fields?
Dan (34:53.142)
So it's basically you're asking about composition of validation.
Evyatar Alush (34:53.537)
Yeah.
Charles Max Wood (34:56.583)
Yeah.
Evyatar Alush (34:58.566)
Yeah, definitely. And this is not a part of Vest itself, but Vest is really built from six or seven packages that I created. One of them is called Enforce, N4S on NPM. And this is the assertion library for Vest. And what it allows you to do is do multiple things. One, it allows you to create your own custom validations and just do
write whatever function that you want and it will be added to the Enforce library. So you can do Enforce data.city and then whatever it is that you want is a proper city name, I don't know. But also Enforce is much more stronger than that and it also has both schema validation library capabilities and also composition capabilities. So you can have Enforce.
rules, they are called rules, each of the functions that's chainable within Enforce. You can have rules that consume rules, that consume rules, or run multiple rules within them so you can have a rule composition within Enforce. So whatever it is that you say can be a predefined composition of rules that's written within
Charles Max Wood (36:20.786)
Okay. And yeah, I'm assuming that that's in the documentation somewhere on the page.
Evyatar Alush (36:27.722)
Oh yeah. Oh yeah. Took me a lot of time to write this documentation for this.
Charles Max Wood (36:31.346)
Right. Yeah, the documentation's actually been pretty good. I've been kind of ducking through it a little bit. So the other question that I have, and I think we've kind of flirted with some parts of this, but a lot of people are using frameworks on the front end and on the back end, right? So maybe I have Express on the back end and then, you know, Nest and Next.js or Nuxt.js or something like that, you know, where, you know, I'm using React or Vue.
So how does this fit into that?
Evyatar Alush (37:06.342)
Um, perfectly. Uh, I'm just kidding. Um, Vest works, um, on the server. You have just one drawback that you need to remember, and it's just one thing to solve, um, and remember when you work with Vest on the server, you do not run your, um, validation suite normally. As I mentioned, your validation suite is stateful, which means that if you run it on the server on multiple requests, each time you run it, it will contain some or bits.
or parts of the validation of the previous user that was validated through it. So all you have to do is just use a helper function that I created. That's also a part of Vest, which is called staticSuite, which is pretty much like the normal suite function, only that on each run, it generates a new suite instance, a new suite state and does not retain it between the runs. So this is the only change that you have to make if you run it on the server.
Other than that, you can use the same validation function.
Dan (38:11.602)
By the way, I didn't mention it before and I wanted to point it out. This library, you know, it has over 2,000 stars on GitHub. So I see that it is actually a pretty popular library. Good for you.
Evyatar Alush (38:26.978)
Thank you. Thank you. Been working hard on it.
Dan (38:30.018)
How long have you been working on it?
Evyatar Alush (38:32.874)
With different iterations over seven years, so I started working on a predecessor to Vest when I worked at Fiverr, another Israeli company. And when I was there, I worked on a framework or a library. It was a library back then. It was called Passable. And when I left the company, I wanted to take Passable with me and I wrote it from scratch as Vest.
and gave it all the stateful capabilities and everything that it is today, and managed to grow it to these 2K stars that it is now.
Dan (39:11.334)
and you're doing all of this on your own free time, as it were. So this is totally a labor of love. This is like not something that's been sponsored by Meta, your current employer or anything like that.
Evyatar Alush (39:15.178)
Yeah. Own time.
Evyatar Alush (39:25.678)
Correct.
Evyatar Alush (39:28.99)
This is my playground. This is my place where I can actually learn new technologies. So I wanted to play with proxies and this allowed me to create enforce, which is an infinitely chainable assertion library, which is something that's very good to use proxies with. This is an example. So everything I want to learn, I try to somehow implement into the library, not forcing it into the library, but actually trying to find the correct place to put it.
Dan (39:29.466)
Uh...
Dan (39:47.134)
Yes.
Charles Max Wood (39:48.51)
Mm-hmm.
Evyatar Alush (39:58.42)
if it makes sense.
Dan (40:00.19)
still, you know, with life, it's kind of challenging, isn't it, to find the time outside work, outside your own, you know, personal, you know, things that you want to do to actually maintain a library like this, like, isn't it?
Evyatar Alush (40:01.998)
Mm-hmm.
Evyatar Alush (40:18.654)
Yeah, definitely. I try to give it a few hours a week. And actually at the moment I've been working on the next major version five for the past 11 months. And this has been really difficult to actually integrate it with my day-to-day life and work. But since this is something I'm very passionate about, I have to find the time for it.
Charles Max Wood (40:45.978)
Yeah, I just also wanted to point out, because this is something that I've been coaching people on lately with their careers, is I highly recommend to people that they have some kind of project outside of work to work on. A lot of times, I'm kind of pointing them more toward a fully furnished application that does something that they're interested in, right? Even if it's just, hey, I actually coached a guy that built.
the thing that tracked assets for a video game for Diablo 3, I think. Right? And it was just all the equipment and stuff, you know, but that was his passion, and so that's what he did. But yeah, what you're talking about where it's, hey, this is my sandbox where I can go and I can try new stuff. That's one of the things that it really, really helps. And what's fun is that sometimes you learn just as much figuring out that this is a really terrible fit. Right? It's like, oh.
Evyatar Alush (41:43.41)
app.
Charles Max Wood (41:43.946)
Okay, I learned all the limitations of this library because those limitations make it not work here. But the flip side is, is you know how it works and you also, in a lot of cases, learn better what applications it really will shine in. And so I just, I love the approach.
Dan (42:01.01)
Another option obviously is to join an existing open source project and contribute into it. You don't have to invent your own. In fact, in many cases, especially for newbies, joining an existing project has a lot of benefits because you know, you get to make impactful contributions to the community from relatively an early stage and you get a lot of feedback and even potentially mentoring
Charles Max Wood (42:23.494)
Yeah.
Dan (42:30.294)
kind of for free. So there are advantages to that as well for sure.
Charles Max Wood (42:35.491)
Oh absolutely.
Dan (42:40.314)
I have another question that I wanted to ask you about the library, but I want to pull back as it were a little bit. So Theo, you know, known as Theo3gg posted a video not so long ago with like it had like the like, so it was so click baity like the title was TypeScript sucks or something like that.
That's not really what the video was about. The video was about the fact that TypeScript is great for people who use libraries, but it places enormous, potentially an enormous burden on library creators. And with that, I really have to agree with Theo's sentiment. Like for us as library users...
TypeScript is great because we get auto-completion and it's really easy to use sophisticated APIs and you're much less likely to make stupid mistakes. But if you're creating non-trivial APIs and you try to make them as strict as possible using TypeScript, not just return any, but be really smart about it, it can get very challenging.
And I'm thinking specifically about some of your APIs. So for example, like you have like we talked about, like you have enforce and longer than or equals to indicate that a certain field has at least a certain amount of characters or letters within it. That's really relevant for alphanumeric fields. It's not relevant for numeric fields.
So you might try to be smart about it and see whether or not the field value that's getting passed into the function is a string or a number and then only provide that autocomplete option for string fields, not for numeric fields. But obviously that makes the TypeScript
Dan (45:02.17)
that you would need to write in the context of the project, much more difficult. And Theo was talking about how they had to invest literally like some care as much effort potentially in creating the TypeScript bindings for particular projects as they, you know, the effort that they basically put into implement the actual functionality. And also in some cases, they actually needed to change their implementation just so that they could.
create the appropriate TypeScript binding for it. So my question to you, I guess, is, you know, what did you do? What do you think about this? How did you deal with TypeScript in this context?
Evyatar Alush (45:45.162)
Oh, that's, as long as the question was, it's also a very loaded question. I think, okay, TypeScript has been a very challenging thing to deal with working on Vest. Beginning with Vest number version one and two, it was not even written in TypeScript. And it was, I had to write the typings manually after the fact.
Dan (45:49.998)
Hahaha
Evyatar Alush (46:15.586)
And when migrating to version three of Vest, I actually rewrote the library in TypeScript, which was a very big challenge. And not even that, what you just mentioned, but think about the infinite chaining of enforce. So you said longer than or equals three, but you can also chain it to is number or is numeric or is not string or is positive or...
whatever it is that you want, and you can infinitely chain it, even to your own extended fields or validations that you defined previously. And every feature like this has been very difficult to implement as a library maintainer, but I do think it also has some upside. Obviously, it made me a much better TypeScript developer. I'm now...
way better in TypeScript than what I used to be. And I know many more features than the average user of TypeScript even knows existing just because I had to find all these weird age cases and capabilities of TypeScript that people do not normally need to use. And in a way, it also allowed me to better learn different tools and different libraries like React.
or Jest and stuff like that. I remember, I think two years ago, I joined React Roundup and Jack Harrington asked me if I've looked at the types for Jest or if I've looked at the types for React because I borrowed some of the internal APIs from them. And I told him, no, I didn't because I didn't think it would help in any way. But
Then right after the podcast, I went and actually looked at how they implemented their typings and I learned a lot both on TypeScript and React and Jess and how they work internally and that improved me as a developer. So this is by the way, a general tip that I have for people. Try to look at the codes for the libraries that you use because you may end up learning a lot from that.
Dan (48:33.058)
for sure. So basically you're saying that you became an expert in TypeScript generics?
Evyatar Alush (48:41.066)
Oh my god. I would say that I've seen way too many deeply nested generics in the past year, and I do not want to see any more generics ever again. That's it.
Charles Max Wood (48:42.878)
Ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha
Dan (48:56.194)
You know, I totally get it. I mean, you know, you mentioned before about how you used proxy in JavaScript to support chaining and that's like the ultimate freedom. You can literally, you know, dynamically at runtime decide how to chain, whatever you want to chain and what's, you know, what to add and what not to add and so forth, but with TypeScript, you need to somehow express all of this statically.
Charles Max Wood (48:56.382)
Ha ha ha!
Evyatar Alush (49:07.021)
Yes.
Dan (49:25.962)
so that it can be handled in compile time. So it's really amusing how the actual implementation is relatively easy and straightforward, but coming up with the type system that actually expresses this and provide some type safety, again, not just making everything any, is really difficult and challenging to do, potentially much more than the actual code.
Evyatar Alush (49:53.454)
Yes, exactly. I just added, pasted in the chat just for you to see what it is that I actually had to do to make that what you just described happen. And this is like, this was one of the more challenging aspects of Vest to actually type because proxies are the ultimate freedom as you said and infinite chaining means you're completely dynamic in the way you do stuff.
and yet I was able to type that with TypeScript, but I think I lost a few years due to that.
Charles Max Wood (50:33.414)
Yeah, I was going to say it seems like in a lot of cases that I see in TypeScript, some of the types are pretty obvious what they are. But yeah, some of them, especially as you get more generic, they get really tough.
Dan (50:33.518)
So basically you're...
Dan (50:47.11)
Yeah, but that's the key point, and that's also the point that Theo was making, is that the difficulty is squarely on the shoulders of the library maintainer. I mean, for the library users, they just benefit. For them, if they just get errors at code time that otherwise they might have only gotten it runtime, if that. And
Charles Max Wood (51:00.224)
Oh, totally.
Evyatar Alush (51:01.825)
Yeah.
Dan (51:16.446)
And for them, it's really simple. They're just using basic types. They don't need to deal with generics. It's all done for them. Yeah.
Evyatar Alush (51:23.67)
Yep. The users... Yeah, and the users do not know how many tears I've shed over this one. Yep. But again, it's a product of love.
Charles Max Wood (51:25.253)
Yep. Yeah, VS Code just magically knows what I'm dealing with.
Dan (51:28.231)
Exactly.
Dan (51:32.546)
Hahaha
Charles Max Wood (51:39.482)
Wow, we'll have somebody get you a teddy bear you can hug while you're working on types.
Evyatar Alush (51:43.806)
Oh, thank you. Thank you. I appreciate that.
Dan (51:49.59)
So you said that you were working on Vest version 5. Currently it's version 4, obviously. Like, what are the big things? Like, what's driving this new major version?
Evyatar Alush (52:01.798)
Yeah, so two things. Actually, it's, it's getting to be more than two things. Um, but the initial incentive for building Vest version five was to switch a few of the defaults. It was to make Vest a little more performant by avoiding doing stuff that Vest does not need to do, or you usually do not care for as a user or as a developer, for example, making it so...
that VEST will stop validating a failing field right after the first test, instead of running all the failing fields or running all the fields for a given test, even if it already knows that a single field is failing. So it was initially about switching some of the defaults and making it so that it will be simpler and require you to do less in order to receive more beneficial and more performant validations. But apart from that,
comes a very big infrastructure update inside and it's mostly about how the data flows within VEST. And I try to imagine that as like adding an elevator to a building after the fact. So VEST version number four had a data flow that was patched in from the outside. So the library was working as a stateless validation library.
And I tried to add some state into it. So I patched like the elevator to the outside of the building. And you know those buildings when you have the outside shaft and you see everything outside. Um, so vest number four, version four was just like that. And the data was working, but I had to hack around it in order to make the library stateful and invest version number five. What I'm doing is.
basically building the entire building around the elevator shaft. So the entire runtime of the library is running around the data flow. So when you go into the validation and the way you end out is without any hacks, without any magic, without any tricks, it just works as if the data is in the place where it's where it belongs.
Dan (54:20.174)
Cool.
Evyatar Alush (54:21.198)
Mm-hmm.
Charles Max Wood (54:21.614)
Yeah. So when do we get it? Going back to the, I spent a bunch of tears on this and you just get it for free.
Evyatar Alush (54:31.131)
Hopefully, within a month, but I've been saying that for the past 5 months, I've been spending the past 5 months mostly yak shaving, sometimes discovering new ideas and new features, but I think it's time I let go. So hopefully within a month, Vest version 5 will be out.
Charles Max Wood (54:53.222)
Nice.
Charles Max Wood (54:59.27)
Don't know if I have anything else that I'm looking to push on, do you Dan? Oh.
Dan (55:05.288)
I'm...
Evyatar Alush (55:05.819)
Well, you could ask the obvious question. You could ask the obvious question, why the hell to use Vest and not use any other library, which it does beg the question because there are tens of thousands validation libraries and some very popular ones like Yup, Enjoy and Zod, which is very popular at the moment and many other ones. So why use it? That's...
That could be a good final question if you want to, but you don't have to.
Dan (55:37.29)
No, go for it.
Charles Max Wood (55:38.626)
I think it is a good question. I guess the reason I didn't go there is because a lot of times there are just a ton of options and it's just down to, hey, I like the approach on this. But beyond the obvious way that you create the validations and the familiarity that you have with something like Jest or some of the testing libraries.
Yeah, are there other reasons to use Vest that I'm just not seeing?
Evyatar Alush (56:13.485)
Well, yes, most of it is around the syntax, but I think the more important thing is around the structure, which means that when you run your form validation, there are three main challenges. One of them is the structure. You don't know where to put your stuff. By the way, am I answering the question? Okay.
Charles Max Wood (56:34.994)
Yeah, answer the question, yeah.
Evyatar Alush (56:39.19)
The reason to use Vest, and by the way, I would say there are three different types of form validation libraries. One is the functional matchers. I would say validator.js, which are perfect at what they do. And there are very specialized tools, functions that tell you whether a value is a number, is an email, they tell you if it's a URL, and they give you a boolean response and they're very good. But.
They lack structure, which means they put the burden on you to decide how to use them, where to use them, and you keep all the logic within your feature, or you still have to make use of that somehow. An extension of that would be schema validation libraries, like Zod or Joy or Happy, which are excellent tools, but they are mostly an extension of the functional matchers. You have to describe your validation or your...
form or form data as a shape, as a JSON shape usually, and then you can run validations on it and while it does give you some structure, it prevents you from having this granular approach towards each of the tests. So for example, if you want to have one field that depends on a different field, this is going to be very difficult to work with. You have to have the whole structure within that field. And also it's very hard when you validate user inputs.
to only validate that single field the user is interacting with, so you end up running the validation for the whole form, and then filter out the results.
Dan (58:18.546)
It's, from my perspective, it's just not the right tool for the job. I mean, a great example is, is password strength. Um, you know, password strength is not really something that's part of the schema, uh, and you might decide to change your, your password requirements. And that should not count as a schema change.
Evyatar Alush (58:23.628)
Mm-hmm.
Evyatar Alush (58:29.148)
Mm-hmm.
Dan (58:44.799)
So certain things are just not appropriate for schema validators, from my perspective.
Evyatar Alush (58:50.726)
Yet they are still highly popular at the moment, even in the client side world. Especially with the third kind of validation libraries, which are not really validation libraries, but more of like form state library specific state managers like React Hook Form or Formic or Vulidate.
Dan (58:57.194)
Yeah, because we developers are lazy.
Charles Max Wood (59:00.357)
Mm-hmm.
Evyatar Alush (59:15.682)
These give you event listeners, they give you components, they give you references that you can put inside your DOM and they manage the form state for you. And they manage the validation for you. And the challenge with them is that, well, first of all, you're usually locked into a specific framework. So if I use one for React, I cannot migrate my validations elsewhere. And also if I want to have some escape hatches and do something that
Charles Max Wood (59:16.094)
Mm-hmm.
Evyatar Alush (59:45.238)
does not support, it's very difficult to get away from the clutches of this library because, well, they take over my UI and not just my form validation or logic. And I think that when you deal with form validation, especially, you have three main problems. You have the problem of structures. You do not know where to put the stuff. You do not know where to put the validation. And you usually make it happen by cramming stuff into your feature logic.
And then when you come to maintain it months later, you want to add another field or make field depend on one another. Then you have to tear apart your feature and re-implement the validation logic if you can even understand what's going on. And the worst part I think is testing. It's really hard to test form validation because when you try, well, forms are the interaction heavy parts of our apps. That's where the money comes in. That's where users click, they toggle the switch, they type.
Charles Max Wood (01:00:39.972)
Mm-hmm.
Evyatar Alush (01:00:43.642)
And this means that because these are the interaction heavy parts of our apps, and that's where the money comes, that's also where the bugs are more likely to happen because well, that's where users fiddle with the most and we do not do enough form validation testing because well, in order to unit test our forms or form validation, we have to first mock user inputs.
then try to see the different combinations and all the data types. And because this is very much UI dependent, it's very hard to test. So I think separating, first of all, form validation from the UI and having a separate structure for it and a very declarative structure that's easy to read, then you can easily maintain it to the future. You can test it because it's only inputs and outputs and you have the full structure for it there, I think is where best shines.
And this is the difference between VEST and all the REST form validation capabilities.
Dan (01:01:44.242)
which basically stems from the fact that it's very declarative, I guess. By the way, I also want to make a comment and one that I hope that you agree with, and that is a general comment about JavaScript form validators, which is, they're great, use them, but don't use them instead of the built-in HTML form validation. Use them on top.
Evyatar Alush (01:01:48.11)
Mm-hmm. Yeah.
Dan (01:02:13.674)
of the built-in form validation. And as an example, if a field in a form is numeric, give it a type number. Don't give it a type text and then use some form validation to validate that it's actually a number. Because not only are you leveraging the built-in browser capabilities, which is always a good idea, it's also great in terms of just user experience, for example, for accessibility
For example, on mobile devices, if the field has a numeric type, then when that field is selected, the keyboard, the virtual keyboard, which would be shown to the user, will be an appropriate virtual keyboard. So for example, for a numeric field, it will have just the numbers and not letters. Or if it's an email field, it might have the at symbol, which otherwise might not be there.
and stuff like that. So use it on top of the built-in browser capabilities, not instead of. And I think that was my point in that discussion that you mentioned that we had conversation that we had years ago was the fact that I saw people, like people were using form validation as like the example for the various frameworks. And the first thing that they would do,
is basically disable all the HTML form validation and just implement everything, you know, using whatever framework they were trying to promote. And that really rubbed me the wrong way. Let's put it this way.
Evyatar Alush (01:03:53.818)
Yeah, I completely agree with that. Make use of your platform's capabilities. And just to add on top of that, while we are talking about DOM validations or web validations, HTML5 validations, VEST can also be used in other contexts as well. It can be used on Node as we mentioned. It can be used on Dano. It can be used on React Native, for example. So yes, sure. Do not only rely on VEST.
for accessibility, for user experience, and for better, and for better compatibility, always make it accessible and semantic and use the platform's capabilities and then augment them with Vest. Sometimes you do not even have JavaScript enabled for some users and you still want to have validations in place, and this is the place where you want to have HTML5 validations and not just JavaScript validations.
Dan (01:04:48.598)
And also related to that, by the way, if your field, for example, is a date field, then rather than using the JavaScript, you're looking at the value property of that field and then converting the string to a date. You can use value as date. There's actually a property called value as date on date fields. Likewise, there's a value as number on numeric fields. And this way you get the value in the,
correct and appropriate type and you don't need to implement your own type conversions. And I found that many even experienced Java and web developers are simply not familiar with these properties, which is a shame.
Anyway.
Charles Max Wood (01:05:39.27)
Sounds good. Well, we are, I agree with everything that was said. I just, I'm kind of focused on flow and yeah, we're kind of the point where we need to do picks. So before we do that though, do we want to just let people know you can go to vestjs.dev, Evitar, I mean, are there other places that people can go to find you online and share ideas or ask questions?
Evyatar Alush (01:06:05.437)
Um
Yeah, I think from vestjs.dev or from my website, ealush.com, they can reach me anywhere pretty much. It also has a list of conferences I'm about to speak at. I'm on X and I'm on threads. I don't remember my usernames, but in either places it's X now, right? Yeah. Well, yeah, I'm on threads.
Dan (01:06:29.034)
You're on threads. Good for you.
You kind of have to be.
Evyatar Alush (01:06:36.718)
They don't force us, but once you're in, you cannot get out. Um, and yeah, so I'm.
Dan (01:06:43.046)
All I know that in my about me slide, in my talks, I'm running out of space because I've got my Twitter, or now X handle, I've got my Mastodon handle, I've got my Blue Sky handle, and soon my threads handle as well. It's like, this is too much.
Charles Max Wood (01:07:01.906)
Yeah, I usually just point people to one place, maybe two and yeah, let them know they can find it from there. One thing that I've actually played with doing, just setting up, I own the domain charlesmaxwood.com, is just setting it up and saying, hey, all my social links are on here. But anyway.
Evyatar Alush (01:07:02.462)
Exactly.
Dan (01:07:24.067)
There is some company, I don't remember which, whose stock taker is C-Max W.
Charles Max Wood (01:07:29.99)
Oh really? They must be cool. All right, well let's do some picks. Now I'm curious who it is. Dan, what are your picks?
Dan (01:07:44.322)
I don't actually have that many picks today, I think, unfortunately. Oh, one pick that I do have is that we watched, uh, Oppenheimer, the movie. Uh, and it's, it, it's a long movie. I would also say that it's not a perfect movie. It's even a slightly flawed movie, but it's a really good movie. You might say that it's a flawed person about, it's a flawed movie about a flawed.
person but also a great movie about a great person. So yeah, in any event I recommend watching it. Do take into account that it's three hours long but it seemed like time flew while we were watching it. We weren't bored or anything. It was a long movie because there was a lot to tell. And yeah, so I recommend it. And no, I haven't watched Barbie yet. So...
Barbie Hymer or whatever it's called, it's not for me yet. That's really what I have in terms of picks. Oh yeah, the ongoing war in Ukraine, still ongoing. People still suffering. Please do whatever you can for the people of Ukraine and those would be my picks for today.
Charles Max Wood (01:09:04.278)
Awesome. The CMAXW stock ticker is for CareMax, which is some kind of health portal. Anyway, just putting it out there because I don't know anything about the company other than just what I looked up in two seconds. Yeah, Oppenheimer looks like a movie that I would enjoy seeing. The Barbie thing, I have a seven-year-old daughter and she just...
She's into other stuff, so it didn't even come up. And I wasn't gonna volunteer to go watch it. Anyway, I'm gonna throw out my picks here real quick. So I have a couple of friends that I get together with usually on Wednesdays and we play board games. And I think I've mentioned this in the past. But yeah, so this last week we played Risk Legacy. Now, if you've played any of the something legacy games.
I think I've played all the Pandemic Legacies there, a few others out there. You actually modify the game as you play it, right? So at the end of each round you like add stickers to the board and destroy cards and stuff like that. This is no different. Most of the other legacy games that I've played have been cooperative though. And so you're playing me right, and so whatever decisions you make as a group...
Charles Max Wood (01:10:27.35)
You know those impact the next game in this one. You're playing against each other. And whatever modifications you make to the board, somebody else can use in the next game to their advantage. And so anyway, it was it was fun. It was a lot of fun, probably more fun because I was the one that won this round. So I'll just you know that doesn't make it a good night. But yeah, we had a good time.
I think I might even like it better than regular risk. But yeah, let me pull up the board game geek on it.
Dan (01:11:03.094)
I haven't played risk in years. We used to play risk a lot while I was in college, but I haven't played it in like forever.
Charles Max Wood (01:11:15.162)
Yeah, I used to play Risk a bunch in high school, a bit in college, but mostly with my high school friends. And so I hadn't played it in probably 10 years. And so I had to kind of reacquaint myself with some of the things that were probably Risk rules more than Risk legacy rules. But yeah, it's board game weight of 2.59. So it's getting a little bit beyond.
what kind of the casual gamer would pick up and play, but we found it fairly approachable. Of course we play all kinds of board games. So anyway, I'm gonna pick that and then, let's see, what else was I gonna pick? So Women's World Cup, I've been watching that. And I just have to say, so the US women are out as of now. That game, they lost it on Sunday.
and it's Monday. So I guess that was yesterday. Anyway, you just can't complain about a game that you lose. And by the time this comes out, I'm sorry, but the spoilers are just not spoilers anymore. You lose to penalty kicks. After five penalty kicks for each team, they were still tied. And so they went to sudden death penalty kicks. And so it was the seventh pair of penalty kicks where the US lost it.
Dan (01:12:29.078)
Ha!
Charles Max Wood (01:12:42.666)
And the goalkeeper actually saved the, like she, she hit the ball up into the air and it just had this wonky spin on it where it came back down inside the goal. And, and it still looked like she had like bounced it out of the goal. Like they had to go back to the replay to make sure that it was a goal that had crossed the line. So, um, and the U S had dominated the whole game. So it was sad to see them lose, but you.
You know, when it was down to that, if you're going to lose, yeah, lose that way.
Dan (01:13:19.242)
That's an interesting point, you know, whether or not you want to lose like on a dagger to the heart or, you know, like lead the entire game and then somehow lose or whatever. I'm not sure that's better. It's a good question.
Charles Max Wood (01:13:36.762)
Well, for me it was especially, and I could go into this forever, but I'm not going to. So watching the U.S. play Portugal in the group phase, they did not show up. Right. They came out of that with a tie. It was a very frustrating game to watch because the U.S. team is way better than what they showed up as. And I had actually.
My rule is not to get on social media until I watch the game because a lot of times it'll spoil it. And so when I turned on the game, I had broken my rule and I knew that the US had lost the game, but I didn't know the details. And so I assumed that they had just showed up the way they showed up at Portugal and just got kicked around the field. And it turned out that wasn't the case. And my deal is if you're going to lose make an awesome showing and they definitely did that. Anyway, I can't be disappointed about that game.
except for that we didn't win and we were the better team. So anyway, it'll be interesting. I'm still rooting for England. So Italy got out in group phase. So those are the teams that I usually pull for. So yeah, so that's my other pick. I took way too long doing that. I'm also working on podcasting for programmers. If you go to top end devs, you can see that under our, I think it's under meetups right now. I'm trying to find a better.
name for it because it's really going to be more of a mastermind group coaching kind of thing that you can join up and just pay per month to be, to have it be part of your deal. So anyway, keep an eye out on that topendevs.com slash podcasting. And yeah, I'll just stop talking cause I've already picked way too much cause I love soccer. Evyatar, what are your picks?
Evyatar Alush (01:15:24.702)
Yeah, you just said meetup and this reminded me of something. I've just been to a very extraordinary meetup, a community meetup here in Israel. It's called Take a Hike by someone called Nir Kaufman. I spoke at that meetup and this is like, I think first of its kind, like second in this community, but off-road meetup. So we all meet up north in the country.
Dan (01:15:37.282)
Hmm.
Evyatar Alush (01:15:52.542)
And we give our tech talks with the audience, with the live audience. And then we set up tents and we go to sleep in those tents. And in the morning we go to an SUV ride up a mountain, make breakfast on the top of the mountain, which is pretty awesome. And then we went down after a few hours to hike in a water trail. It was really, really fun. It was...
Pretty much all, it was the first kind of experience like that I've ever had. And it was an awesome way to connect with the community. I really enjoyed this one. So this is just because you mentioned a meetup. And the second pick I had, oh yeah. Yeah.
Charles Max Wood (01:16:33.18)
Mm-hmm.
Dan (01:16:34.814)
Before you go to that, I just need to mention that Nier Kaufman is indeed an amazing guy. He used to be a colleague of mine at Next Insurance. I really need to get him to be a guest on our podcast. He's an amazing person.
Charles Max Wood (01:16:35.794)
That sounds awesome.
Charles Max Wood (01:16:52.09)
Yeah, we've had him on some of the shows before, because I know I've talked to him. So I think it was on the Angular show. Yep.
Dan (01:16:55.254)
Yeah, probably on the Angular shows. Yeah, he's one of the thought leaders in the Angular community.
Evyatar Alush (01:17:05.046)
Yeah, and Nier is amazing. Um, and so this was really, really fun. And the second pick is just because you mentioned it before, uh, Dan, uh, is my talk from the React Next, um, conference, which I talk about building React context from scratch in vanilla JavaScript. It's already on YouTube. I'm sharing it with you. And also if you want to meet me, uh, anytime.
I'm traveling this year, I'm going to Germany to speak at Code Talks in September. I'm going to be in full stack Europe in Belgium and International JS Conference in Singapore in December. So any of those, if you want to meet me, I'm going to be there.
Charles Max Wood (01:17:47.134)
Cool. Good deal. Yeah. Some of those sound way fun too. All right, well let's go ahead and wrap it up here. And yeah, thanks for coming. Till next time, max out.
Evyatar Alush (01:17:48.324)
Mm-hmm.
Dan (01:17:49.614)
Good for you.
Dan (01:18:01.675)
Bye.
Evyatar Alush (01:18:02.958)
Bye bye.
Charles Max Wood (01:18:03.35)
hang in there for a second while we
Evyatar Alush (01:18:05.522)
Yeah.