Handling error state, reviewing code, and request data objects

Michael (00:08)
Hey, I'm Michael Durenda.

Jake (00:10)
And I'm Jake Bennett.

Michael (00:11)
and welcome to episode 152 of the North Meets South web podcast.

Jake (00:20)
You know, I like our long intro music. I just, it was such a good song, such a good intro. I mean, you know?

Michael (00:25)
It still is, but you listen to all the podcasts now and all of them are just straight into it and, and since that is where everybody else.

Jake (00:31)
Hey, is that who we are, Michael? Are we just everybody else? We're just following. We're just following the whole, you know, no uniqueness necessary. Just you know, follow the limit lemmings right off the cliff.

Michael (00:38)
I, I put all of my uniqueness. No, no, I put all of my uniqueness into other things. It's my hair, my hair. Someone said to me the other day, what color is coming next? I said, I don't know. It's just, Eli's got his school sports day coming up next week, I think. So I will, I will go, he's in team blue. So I will, I'll put some blue stuff in my hair for that.

Jake (00:47)
into your hairstyle. I get it. I understand. Yup, your hair, I understand. Fair enough. Although...

It's looking quite blonde.

There you go, there you go. Nice. Hey, it's like that surfer blonde. It's nearing the end of the summer, you're mourning the loss of summertime. So hey, I get it. I understand, I understand. Hey, today I got, see if you can tell what I'm showing you.

Michael (01:09)
They're just extreme blonde at the moment.


got some new AirPods at last.

Jake (01:28)
Yes, because the old ones were absolute garbage. And the only way I know they did it. Yeah, and they would the left. Yeah, yeah.

Michael (01:32)
Did they go in your ear? Was that the thing? They crackle, they crackle and crackle and crackle. And then eventually you just put up with it initially and then you reset them a few times and they get better and then they crackle again. And then it's like really annoying, but you're like, no, it's not that bad. Like I don't need to, and then re, and I was complaining to re about it. And she's like, just get new ones. I said, no, that's fine. And then she had

Jake (01:50)
Oh, so bad.

Michael (01:58)
reason to use them one time and she was like, get new ones now you can't you can't do this now

Jake (02:02)
Yeah, they're so bad. And like honestly, like my right mic, they wouldn't work if the microphone was on the right ear. So I had to switch it to the left ear because the microphone stopped working. And so like if I ever just had the right one in a phone call came and I couldn't pick it up, so that's kind of left was annoying. And then when I would put my finger on my left one to like adjust it, it would whistle like a whee in my ear. Really high pitched. Oh, so annoying.

Michael (02:08)
Yeah, yeah, you have to switch it. Yeah.


Yeah, every now and then. And it would just happen at random as well. And you'd be like, ah. So I think, you know, it's, it's just the AirPods, but yeah, the new, the new ones are nice. I, they often fall out of my pocket. And so they just end up somewhere and it's the worst when they fall out of my pocket when I do, you know, bedtime with, with the kids and they're out, they're like left in the bed. And it's like, so now, you know, they've got fine my they're much better with, but like

Jake (02:27)
Yes, exactly. And so finally, yes.

Ah, okay.

Yeah, yeah. Good luck trying to find them in there.

Yes, which is so nice. The little microphone at the bottom. Yeah.

Michael (02:51)
And they make the sound as well with a new case, which, which you can't really do when you, you know, suspect that you've dropped them in someone's bed because you don't want to wake them up with that chirping, but they are quite handy. Much easier to find now.

Jake (02:59)

Yeah, because the old ones, so let's see if you if you couldn't find them, you can find them. There was no, you know, yeah. And so

Michael (03:05)
You couldn't find it. Yeah. And if you go to the Ben Orenstein, Adam Wathen school of AirPods, as soon as you have to spend more than 30 seconds looking for them, you just go on apple.com and you buy Nuance. That's it. They'll turn up eventually, but you just get another pair. I think Adam's got like five or six fixed pairs. The last time I saw his, he's, he's like, you know, you know, you go to the swingers party and they put the keys in the bowl where he's just got a bowl full of AirPods.

Jake (03:17)
That's hilarious.

Oh, they are awesome. Oh yeah, I mean.

Mm-hmm. Yep, just doesn't matter. They're all interchangeable. Just pick up a pair, put them in your ears. That's pretty funny. Yeah, that's pretty funny. I was looking at AirPod Max and I'm like, I don't know. I would consider getting some just for like when I'm sitting down for a long coding session. Yeah, do you use them?

Michael (03:35)

Uh, usually only when I go to the office, cause of the, cause like these are good for noise canceling, but they don't like block sound, whereas those are much better, the over eating to just block out. Um, but I don't, when I'm at home, I've just got the app, the home pods here. So I've just got the home pods going on all the time. I don't really, they're good at night when I want, like there are some TV shows that I want to, you know, like we just watch.

Jake (03:52)

Sure. Yeah, yeah, yeah.

Yep. And I've got to office it. Yeah. Yep.

Michael (04:16)
And it's fine if it's like it's dialogue or there's not much going on, but there are some shows like Halo, for example. I want to watch that with full volume. So I'll put the, the max on.

Jake (04:25)
Is that good? Should I watch that? Is it on what? What channel is that? Is it on Netflix or is it on Apple TV? Plot? What is it? Oh, Paramount. Oh, OK. I could get there.

Michael (04:29)
They, it's on Paramount Plus. It's Paramount Plus. Season one had a really strong pilot and then a lot of like filler between episodes like two and episode seven, and then like two good episodes or whatever it was, three good episodes to close out the season and then kind of ended. And then this season I think is much more in line with like the action aspects of Halo.

Jake (04:44)

Michael (04:59)
But I think there's a lot of reticence around the fact that for spoilers, skip forward 30 seconds, um, that he, like that they're not wearing their suits. Like there's a lot of the, the like not act, there's still action parts, but there are a lot of like action parts out of their like master chief suit. So, um, I think there's some complaints about that, but they've, they've spent a lot of time. I look, I, I enjoy it.

Jake (05:06)
Okay, okay.

Hmm, interesting.

Michael (05:29)
You know, the episodes are 45, 50 minutes, an hour long.

Jake (05:32)
Did you play Halo as well growing up? Like did you know Halo, it's storyline, all that stuff?

Michael (05:35)
I've played and finished all of the like single player Halo games. I never got into like ODST or the multiplayer stuff, but yeah.

Jake (05:41)
See, that would be like, to me, to me that'd be like if they came out with like a Half-Life show or something. Because I was like, you know, that was my jam when I was a kid, loved that stuff. But...

Michael (05:48)

Yep. They're doing, um, what's going on? Something comes out next month. There's borderlands, which is a movie that trailer came out a couple of weeks ago. And there is fallout. I think HBO has picked up and the fallout, um, is, is out next month, which, which would be interesting to watch. I've, I've never played fallout. I couldn't, it gave me the, gave me the, the headaches and the.

Jake (05:59)
Ah, mhm, okay. Sure. Ah, really, fallout, that sounds interesting.

Michael (06:16)
And the head spins of there, there are some games that just do it to me where they just, I can't play them because the motion or whatever, they just give me terrible headaches and, and stuff. So that was one of those games, but I'm, I'm into. Watching, you know, TV shows and things like that. So I would definitely give that a, give that a go.

Jake (06:23)
Sure. Yeah.

So we've got.

Yeah, I feel like I'm more about a movie than TV series. Now, some people will be like, oh yeah, but a TV series can give like so much further in depth and everything. And it's like, yeah, it can, but I just don't have the patience or the commitment. It's like, I want to go and watch two hour movies. So I want to watch Dune Two, for example. Like it was like three hours. It was so good though. So good. Really long, but really good. And I'm glad they didn't make it a TV series. It's just not the same. Like you can't watch a TV series in IMAX. You know what I mean? So it's like.

Michael (06:42)





Yeah. Well, they're doing Harry Potter. They're revisiting Harry Potter. I think HBO or Max or whoever they've picked it up and they're going to do like each book will be a season of the show. So it'd be interesting to see how they kind of do that and pull it off.

Jake (07:01)
It was really fun.

Oh, that's fun. Uh huh.

That's kind of cool. Sure. There's a big enough fan base. It'll be fine. You know, Harry Potter is so popular even I mean, just with even with like the young generation now, like my kids love the Harry Potter books. And so that's funny. It just sticks around. It's got a lot of staying power. Hey, help me understand here. What does reticence mean?

Michael (07:17)


It certainly does.

Like, how about it? Yeah. It's a Redison like his reservation. Yeah. It's like when you kind of. Resort like people were kind of against it because it's like, people want essentially pick up the story and all of the action and whatever, like basically pick up the campaign from the game and put it into a TV series, which is like.

Jake (07:32)
So there's a lot of reticence around and I was like, I don't know what that word means.

I know that's so funny because we use words and then we're like, I know what it means in context. Okay.


Yeah, yep, yep.

Michael (07:59)
Gamers are always like that. They're like, it's not exactly how I want it, then it's no good. And it's like, just enjoy the thing for what it is. Yeah, yeah, yeah.

Jake (08:02)
I know it's like the people who read the books first and like, you know, it's like, I read the books, it's not like the books. It's like, I know it's different on purpose. Like it's not supposed to be the book.

Michael (08:10)
I think, and I like, I learned about this in like eighth grade English, ninth grade English, it's like when they adapt books to different mediums, whether TV or movie, they can't just do the same thing. Like the storytelling has to be different in the visual medium. You don't get, you know, the, um, the ex the exposition and like all of the explanatory stuff, you don't know what the characters are thinking. Like you have to tell the story in a different way.

And so, yeah, look, it's like, maybe it's not true to the story. You know, everyone goes on, there's lots of law around it. Um, and, and things like that. When Mortal Kombat, the new Mortal Kombat movie that came out a couple of years ago. Everyone was kind of like this, there's so much law and the story to Mortal Kombat that you didn't have to, like you, you inserted a character into the movie to tell the story of like.

Jake (08:53)
I didn't see that one, but I know what it was. Yeah, it looked interesting.

Michael (09:09)
what Mortal Kombat is. And I think I see it from that point of view where you're making a movie for a certain demographic. Like you're making a movie for Mortal Kombat fans. But I think they went to the point where they were like, we're trying to bring new people into it. And I think when you do that, you are making a different piece of media.

Jake (09:09)
Hmm. Mm-hmm, mm-hmm.

Yeah, totally.

Michael (09:33)
You're trying to pick up a new audience. It's like there's, there's 20 or 30 years of Mortal Kombat. People can go back. They don't need the backstory. They don't need to know, like there are elements of it, but don't like create a character to tell the story because you, you don't want to risk people, you know, not understanding something so they can go and check that stuff out after. I think, you know, that's, that's the same with halo. Like just tell a story.

Jake (10:00)
There we go. Well, uh, those, uh, those kind of, uh, 10 minutes of something you didn't come to maybe to hear, but maybe you did. I don't know. Sometimes people are like, Oh no, I like the sort of pre show who literally who does. I mean, I remember back when we first started, it was, we had people on all the time from like, you know, we had, um, freak on and we had Marcel and we had Taylor and Adam and you know, all those folks, and now we just get on a chat. I mean, maybe we should line up more guests. I don't know.

Michael (10:01)

Who knows what this podcast is anyway?

Mm hmm. Yeah. Maybe.

Jake (10:31)
Yeah, so guess what I broke out again today? Actually yesterday. State machines, of course. X state for the win. So there was this, here's, let me tell you the scenario, okay? There was a field and we needed to be able to have a file number entered in the field. And then when they pressed enter or tabbed out, it needed to go fetch three different things. And as long as all three of them returned successfully, you needed to put a green checkbox in.

Michael (10:35)
Would you break out today? Yes, today. State machines.


Jake (10:59)
but if it did not, you needed to put a red error symbol. Well, if any of them fail, you can immediately put the error symbol in, but you have to wait until all three of them succeed to put the green checkbox in, right? And if you get one success and an error, you just show up throw error. But if you get a success after an error, you have to make sure it doesn't change back to success because it's not success, it's error, right? And then you can't do anything to change that error state or that success state unless you

Michael (10:59)


Jake (11:28)
change the file number, right? So if you had, let's say like one, two, three, and it errored, well, we're not gonna retry one, two, three unless you change it, because it's invalid, right? So it's like, if you change it, if you do on change, then you need to change it back to a ready state so it can go from ready to loading again, right? So this was a complicated issue. And like it became apparent because the developer who was working on it was inspecting like five different fields.

all at the same time to determine what state he was in. And it became obvious to me that it wasn't going to work. It wasn't going to be sustainable when I was having two icons overlaid on top of each other at the same time, right? There was like an error icon and a loading icon and a success icon at the same time. It was like, how do you get into that weird state? But it's possible because you have all these weird... Yeah, right. Exactly. And so Schrodinger's icon. Yeah. And so anyway, really interesting. I should share it. But

Michael (12:02)

Added a sixth field. Yeah.

trading his icon. Yeah. Mr. case. Yep.

state machines to the rescue again.

Jake (12:30)
Exactly, that's literally what it was. And so we had a ready state, a loading state, a success state and an error state. But the thing that was cool about this is in the success state, you had two different, well, you had a event that I was listening for in the, sorry, in the loading state, you had an event that you could listen for, success, okay, or error. So if you had error, you'd immediately transition to the error state, right? But if you had success,

you wouldn't do anything immediately. You would just kind of wait, right? So if you had a success state, what you would do is instead of transitioning to another event, you would run an action. And the action was increment success count. So when you're on loading state, you could accept one of two events, error or success. Error take you immediately to the error state. Success increments the success count. But every time you would come to the loading state, again, every time any event that it was listening for would come in,

Michael (13:15)

Jake (13:26)
there was this thing called always, and it would evaluate this statement every time. And so what it was, is it was an always, and it was a conditional that said, if you've reached a success count of three, then you should target the success state. And so it would just, you would hit it, you know, I got success on one of them. Okay, great, we'll increment the count. Success on another one. Okay, great, we'll increment the count. Success on the third one. Okay, great, we'll increment the count. Oh, is it three? Yes, it is. Transition to that other state. So that was the magic sort of.

stuff there. And then the nice thing is, you know, if you transition from the loading state to the error state, error state doesn't listen for success events anymore. So it doesn't matter. You don't if you got a success event after an error, it's not going to change it back to success because it can't, it's not listening for that anymore. So it was perfect. It was just the perfect use case for when you would need the state machine. And it's so beautiful. Like no, I got rid of literally eight variables. Like it was just so nice. And so yeah, if you're looking

Michael (14:08)

It's nice to have that real world example as well, like mindful of the fact that you have this talk coming up to kind of like refresh it a little bit if you wanted, you've got a real example to use rather than the contrived, you know, I mean, the invoice is a good one as any, but having, you know, we're telling the same story, but with a different example from a real world application is, is always nice to have. And it's not always possible, obviously.

Jake (14:28)
Yes. Yep.


Michael (14:47)
when, when you're giving a talk to translate like something from your work into the talk, but having the ability to do that and having like this tangible thing that it's like, I've not just come up with this contrived example, because then you have to think about all of the situations in which you might apply that or use that for the purposes of telling or giving the talk. You've got like, no, these are the things that I have proven to be true with a real concrete example.

Jake (15:17)
Yep, yep, exactly. Like this is a real world thing that I actually did that I used this for. So anyway, yeah, that was really cool. And it cleaned it up a lot and it felt really nice to be like, ah, validate it again. Like, yes, this is the correct solution for this location. Not always is it, but a lot of times it is. And so that felt good. I was trying to see if there's any of the libraries I could use to do it in a smaller form, like in a much smaller way, but it was just like, nah, I'll just go back to Xstate, Xstate for JavaScript stuff. So.

Michael (15:22)


Jake (15:47)
So that's good. So that was sort of a recent thing I've been working on. I mean, other than that, it's basically been just all out sprints, man. We've just been killing it. Like, we've got so many things in flight right now. It's kind of crazy. I was messaging a guy that's like a senior and they come to me, Hey, dude, what would you think about spending a couple of hours a week, like a day a week, just reviewing pull requests for me? Just like I just need another set of eyes from a senior to just be take a look and say, like, oh, no, it doesn't look right. Like, or you didn't think about this or you know what I mean?

Michael (15:58)


Jake (16:16)
I don't need them to write code. I just need them to look at code and just point out areas where it's like that doesn't seem like correct. You know, because it's like there's like six, seven, eight, nine, ten, twelve pull requests out there at a time. And it's like I can get to some of them, but I can't get to all of them. And it's like I don't want everybody waiting on me. So.

Michael (16:16)

Yeah. Yep. Well, now that, now that we've kind of combined our backend and front end into a single repository, there are like 20 or 30 pull requests on the go at any one time and it's like, okay, I only want to look at the backend one. So I forced everyone to, to tag or label their, their PRs. And so I will only look at the backend ones and, and usually only either if I'm like between tasks or someone specifically asked me to look at something.

Jake (16:42)

Just tag them, yeah.

Michael (16:58)
because my code review, like we all review each other's code, which is good. And now that the team has grown, there's, there's people in at different levels that like, you can write the code, you can review the code, even like the junior reviewing up to a senior's code is good as well, because they can ask, they're going to ask questions, they're not just going to assume that something is correct. Or they're going to see things in a different way. They won't understand things necessarily. Like if you use a collection of pipeline, they might ask, what are you doing here? Or why did you do it this way? Whatever. So it's.

Jake (17:03)
Sure, sure.

Michael (17:28)
It's good from that perspective to kind of get the team writing more approachable code, I think, rather than just like benevolent me reviewing everyone's and it like takes a lot of time as well, but I find that when, when I'm in a position to review code, the outcomes are very different to when, you know, other people are reviewing code and I'll find things that others won't see, or I have a different level. And there's like a lot of it is also the feel like, you know,

When, when you're reviewing code, there's the feel of the code.

Jake (17:57)
Yeah, I totally do. Yeah. So it's like your preference. Yeah, it's just like, hey, this doesn't feel right. It's like, well, why? Where's the where's the rule that tells me that's not the case? It's like, well, there's no rule. It's just doesn't feel right.

Michael (18:02)
And it, and it's hard to kind of, yeah, there's no rule, but like when you, when you look at like a constructor and using constructor property promotion, like where do you draw the line between all of those things being on one line? Well, sorry, not constructed property promotion is probably not a good example, but like a method, where do you draw the line between having all of the parameters on one line and when do you start to split it up? So it's one per line, you know? And it's like,

Jake (18:18)
Mm-hmm. Oh, sure.

Sure. Yeah.

Michael (18:32)
And I think like our sort of soft rule is when it gets to like 120 characters, you kind of start splitting it up. Just, just to kind of make it easier to read, especially now that we're kind of embracing types a bit more and we're using more complicated method signatures. When you've got like, this is an array or null, you know, that kind of stuff or a nullable array, and then you've got like, this is an object of type, whatever. And so these things then start taking up more room.

Jake (18:41)
Yeah, yeah.

Michael (19:00)
And it's not just a matter of looking at like dollar variable equals, you know, now comma or whatever. Now you're looking at like two or three pieces of information potentially for every method argument. So splitting them up onto one line, you know, each of them being on one line, it makes it a bit easier to digest as well. And sometimes you might look at it and you go, I'm, you know, passing too many variables in here. Maybe I've missed something in that. You know, it's, you know, that kind of thing where

rewriting the code in a, in a different visual presentation, you know, from one line to five lines makes you sort of stop and think a little bit more about what you have actually written and whether or not it is the most appropriate way of writing that piece of code. You might find, Oh, we need to actually set something as a, as an instance property on the, on the class and then reference that rather than passing it between methods and so on and so forth. So it does help.

I think to, to reveal some patterns about your own code and certainly makes it easier to approach refactoring in terms of like, you know, what it ends up looking like.

Jake (20:11)
Yeah. Yeah, or things like, how often should you use a form request? If you only have one thing to validate, should you use a form request to do that? Or shouldn't you? Do you know what I mean? Which one should you use? So anyway, some of those things are coding standard things. You literally could probably, you could enforce those things with Pest's architecture plugin and things like that probably. But yeah.

Michael (20:21)

sure. Yeah. Do you just on form requests? Cause I know that you're a fan of them. Do you use sparsees Laravel data package at all?

Jake (20:39)
I am, yeah.

I don't. We've talked about it before. You and I have actually, and we've been talking about it a little bit inside of our other chat as far as like where should like the line be drawn for when a form request is used or if you should say like, yeah, we only use form requests up until this point. So we say, you know, once you're out of the controller, it should no longer be a form request. It should now be something your domain owns, it should be a DTO, it should be something like that.

Michael (20:49)



Jake (21:14)
We do have places in our code where the request is literally drilled three layers deep, right? That's not great. So I could see using Spasi's package. It certainly makes it a lot easier, right? But I'm sure there's some, using any tool for long enough, you'll find the spots in which it fails, right? Where it's insufficient and you have to do something else. So I can't speak to that, though, because we don't use it. So I know you guys do, though. How's it going with it?

Michael (21:27)


Yeah. All right. So I will pose you then a, it's not a hypothetical, it's hypothetical for you, but it's the reality for me. We have a form request, right? It does, it has all of its rules. It does the validation. We then take that and we pass it into the Laravel data object. Now the Laravel data objects have these magic creation methods. So you go like person name, colon, colon from.

Jake (21:47)

Michael (22:11)
And then you pass it the request. And what it will do is it will look for either a from request method on the, um, on, on that DT, that data object and resolve it using that. And then you can do all kinds of creative things like from model or from user model. So you could

Jake (22:14)
Okay, yep.

Yep. That makes sense. Uh huh.

Michael (22:36)
You could specifically do this and then Lara the package itself uses reflection and some magic to kind of figure out like of these magic creation methods. So they all start with from they're all public, they're all static, which one best maps to this thing that I have been passed and it kind of instantiates the object now from model, from array, from string, these are all fine. What I find, and I want to hear your take on this is that if it's building the

Jake (22:52)

Michael (23:05)
from, if it's building the data object from a request, it does its own validation to make sure that all of the input in the request. So the stuff you take from like request, input request, Jason, or whatever maps to a property on the data object before it calls the from request method. Right. So in the example of like person data, you might have

Jake (23:21)
Yep, yep.


Michael (23:34)
your data object as name, email, phone number, for simplicity sake. But in the request, we're capturing first name, last name, email, phone number. So because, and because in the specific instance of a request, what it does is it passes it through this like pipeline of, um, stuff.

Jake (23:46)
Mm-hmm. Yep.

Michael (24:01)
where it normalizes the request, it does all this other kind of stuff. But the thing that has tripped me up is that we'll also do a level of validation, that there is a property on your data object that matches your request. So keeping in mind that I have a request that has first name, last name, phone, and email, and a data object that has name, phone, and email, in my from request method, I would then take first name, last name,

Jake (24:20)
Right. Yeah.

Michael (24:29)
concatenate it into name and then instantiate the object. But because the request does not match the DTO exactly, it hits the validation error in the Laravel data package that says this field is required, name, name is required, but it's not set. So then you've got to like do these gymnastics around using this other prepare for pipeline method, which then allows you to kind of massage the request into a format that matches.

Jake (24:30)
Yeah, right. Yep.

Michael (24:59)
the DTO, but it just, it kind of muddies things up a little bit, I think. Um, and so, and so now we've got like two places doing validation where I would expect that all of that request validation happens in the request object and that you don't try and magic it up for me in the data object itself.

Jake (25:04)
Yeah, I think it, yeah.


Yeah, well, because it's also not even like the rules that you have specified in your form requests, right? It's different. It's like the it's magic rules that aren't even really defined anywhere except for you know that the package is going to do it.

Michael (25:33)
was it's based on the definition of the, so you've, so it's based on what's in the constructor, right? Public name, public string name. Yeah. Public string name, public string phone number, public string email. Like those are the three things. So it would look to see if there is a request.

Jake (25:36)
So like if you say public first name, public, yeah, if you say public full name, yeah, exactly, sure.

Yeah, I guess the thing that would be I guess the thing that would be nice is if it did something like if it had like a use validates before request or something like that, if there was like a trait or something that you could turn on or off, because then that would make a lot of sense. But to say like that from request method is just automatically sort of getting this decorator around it that's going to do all the validation stuff like that feels a little bit weird. It feels like because now what you have to do is you almost have to like

Michael (26:00)

Jake (26:15)
create your own static method on that thing called from our requests, you know what I mean? And then pass the form request that way and then handle it by instantiating it yourself.

Michael (26:23)
Yeah. Well, yeah. I mean, the problem is, is that it specifically checks if the input to the from method is an instance of request. And if it is, it will shove it through this pipeline, right? So you don't even get access to your own magic method until it's run through that process. And so, you know, there are two options, right? It's either conform your, your request exactly to the data object. Or.

Jake (26:28)
Mm. Mm-hmm.

Yeah, yeah, yeah. And then it, yeah. Yeah, that makes sense.

Ah, that rough. No, that's rough.

Yeah. Yeah, yeah.

Michael (26:51)
actually there's three options. So the option one is to conform your request. The second option is to call from request directly, which then skips the magic creation. And the third one is to use, which is what we've done, is to use like the without validation attribute on those properties to specifically say, don't try and be smart about this. I know how I'm gonna massage this in the from request method. Like I don't...

Jake (26:52)
Or use your other, go ahead, yeah, you figured it out, you said it, because I'm sure I'm not gonna get it right.

Mm-hmm. OK, yep.

Ah, yeah.

Michael (27:19)
And I haven't gone into like the history, the commit history of the, of the package or, or to try and figure out like why this was implemented, like what the thought process was behind it, but, but for me, um, it, it feels a bit counter, like it's, it's not a PHP agnostic package either. It's specifically for Laravel. So it's like, I'm giving you a form request. You know that it's a form request, which I have already validated.

I want to use the from request method, which I will do the mapping from what's in the request to what's in the DTO, but you are preventing that from happening. By, you know, doing this level of validation. So I just wanted like a second, third, fifth set of eyes at this point is to be like, is this weird, like, should I get onto Frank and be like, excuse me.

Jake (28:09)
Yeah, I mean, like, because I think what they've done is they've decided to take the road of saying that we are going to define the conventions and now you can you can adhere to the conventions or you can do the long way and opt out by yourself. Right. And so I think that's probably the route that they've decided to go and that's very spousy of them right like now they so they give you an escape hatch. But they're basically saying if you want to use this package, this is the way that we use it. And we've decided to just

Michael (28:14)
Sir, what have you done?

Mm-hmm. Yeah.

It is.

Jake (28:38)
follow strictly our requests, which maps straight into our DTOs, which maps straight into our models, which maps straight into our, you know what I mean? Or maybe something like that. So if it was me doing it, yeah. I mean, I think, let me think about how I would do it.

Michael (28:46)

Jake (28:57)
If I was doing it myself, what I might do is I might call the from request method directly in my controller. Yeah. And then just let my from request method handle that. And then using from request would just do, you know, it's skip the validation stuff. And I could still use from anywhere else knowing it's, you know, if I'm using that request method, it's not if I'm using that request object, it's not going to work. But that's okay. I would just use from request in those instances. And I guess document well that that's why it is that way.

Michael (28:57)
I guess I can see the thought process.


Yeah. I suppose if you look at it from the perspective of the Laravel data object that is created from a form request is being done with the specific intent to give a type, to give typed, you know, in, uh, inferred access to the properties. Then yes, it makes sense that, you know, this is, this is to replace basically that, that request object wholesale.

Jake (29:27)


Michael (29:57)
And so whatever you map in the DTO needs to match exactly what is in their request. And it's to stop you from passing the request around and using like request import all the way through. Cause you know, we know that that's error prone that you could have a typo in the string, you request input, request import, you know, name, and you forget the E and it's just nam and then you end up with null can be trickier to diagnose than to do request nam on.

Jake (30:07)
Yep, yep.

Yeah, yeah, right, right.

Michael (30:25)
you know, the typed object, which will tell you, no, NAM doesn't exist here. So I guess if that's the intent, it's just that, you know, you're not always in control of the data coming into that request, I suppose, but you're always in control of the, of the data object. So maybe, maybe it's a PR that I send to the documentation to say that like, this is the specific intent, just to clarify that. And like, I'm happy, I'm happy to have the conversation. I think with, I think Ruben.

is responsible for the package to say like, why is it like this? And if the, if my understanding based on what we've just said is, is correct, then can I send a PR to the docs to say like, this is the intent of using the form request, using the from request functionality, and then, and then it's like clear and then everyone understands. Cause like it tripped me up for ages and I was trying to find a way around it. And I was, you know, source diving through the package and it's, it's created in such a way that it's.

Jake (31:11)
Yeah. It's a map one to one. Yeah.

Michael (31:24)
Like it makes sense, but it's, you know, you've got to jump through a few classes to find out where this behavior is actually happening and then, and going, oh, okay, I understand why this is happening now, but I don't understand why it's happening kind of thing. So.

Jake (31:32)
Oh, there it is. I can see. Yeah, it's an illuminate request. Yeah. Yeah, that makes sense. I thought when you originally saying it, you were saying that it would basically run the validation step again on your form request. I was like, that seems odd. Like, it seems like, I got it. Yeah.

Michael (31:45)
Yeah, no, it's doing, it's doing its own like assertions against like, you know, it's using reflection to find out, you know, what are all the properties? What are their types? Does this thing exist? Is it of the correct type? And I, and like, because I haven't actually got it working in the way that I guess the package intends it to work. You know, I assume that if you type it as a string, it's going to use request input. But if you, if you type it as an integer, it'll use request integer or request Boolean to kind of make sure that all of those types match up for you.

Jake (31:53)
Yeah, sure.

I guess so.


Here's one other option for you. Are you ready? The other option you could do is you could, in your form request object, you could append a full name attribute to the request in the form request object. So you could say like after validation, and then that's going to make sure that everything's valid. And then you could say, I think it's, I don't remember if it's like this request or this attribute push or something like that anyway.

Michael (32:15)

Yeah, you can merge or whatever in there. Yeah.

Jake (32:39)
You can set the value. Yeah, you can set the value, basically. And so then you could just do it in there. And then any time you get the form request, as long as it's valid, it's going to push that value in there. And then when you pass it through, it's just going to set it. No big deal. That way you don't have to do any of that other stuff. It would just work. And that would work every time. I mean, as long as you validated it, I suppose, but what you're going to do, I mean, it's going to happen automatically when you use form requests in the controller. So it's just where do you want to put the logic, you know? Yeah.

Michael (32:51)
Mm. Mm-hmm.

Yeah. Yep.

Yeah, I think.

Yeah. I think now having, having this conversation, yeah. I think now having this conversation, having said it out loud, I've like talked myself into believing that it is the correct approach with the assumption that like, that is exactly what the intent is that, you know, that, that the re that the data object should in fact map the request one to one. And so yes, you are defining the things in two places, but it does mean that you get a typed object as you go.

Jake (33:17)
Yeah, I think so.

Michael (33:33)
you know, through the application depths.

Jake (33:36)
Yep. Exactly.

Michael (33:38)
We've hacked around it for now and we're just leaving it as at that, but, um, it'll be something to keep in mind for future because like none of the other people on my team that had been working with it had encountered this problem. And I'm like, have you not encountered, like, are you calling the from request method directly? Are you or, but I, but if I, I think I figured in the end that they were in fact, yeah, doing the mapping of the request, the form requests one to one with the, the data object, and that makes sense that they never hit the issue then.

Jake (33:54)
Right, right.

Yeah. Yeah, exactly, exactly. Yeah, and it is really nice just to have that typed object you can pass around and new up in tests and all that stuff without having to have a form request and then pass it. Yeah, yeah, really nice. Well, hey dude, we're at our time. Yes, yes, indeed, we are at our time. Hey, thanks folks for hanging out with us, 152. I was gonna say, not Laravel News. I don't know if you saw that audio slash 152 for show notes. Hit us up on.

Michael (34:14)
Yeah, from a code safety perspective. Yeah, it's good. Yep. All right. I've talked myself into thinking it's okay. We are.

Jake (34:34)
twitter at Michael Dornett, Jacob Bennett or at North South Audio. Rate us up on your podcast, catch our choice, 5 stars would be amazing. Until next time folks, we'll see ya. Peace.

Michael (34:43)

Handling error state, reviewing code, and request data objects
Broadcast by