Rendering Modal From Props0:00
We've now figured out how to visit the edit route while still showing the index page, but we still need to show the modal on top of it. So remember these are the page props for the index route. So here you can see all the User models that we are showing in the table. And here is our _modal object with the base URL, the modal component and the modal props. So this is the single User that we want to edit. Let's go into the code.
So this is the single User that we want to edit. Let's go into the code and see how we currently render backend power modocs. Let's open our layout file. And this is where we currently render our modal and we only render it when this modal value is set. And that comes from this useModal helper. In this helper file we are making an XHR request with Axios and then we, we get a response, we solve the component, which is actually the modal component.
Extracting setModal Helper0:53
and then we, we get a response, we solve the component, which is actually the modal component. And then we set this modal value. And actually we don't need to make another Ajax request because we already have that modal data on the page props. So we just want to reuse this piece of code. So I'm gonna extract it, let's copy it and I'm gonna create a new function and I call it setModal. It's gonna accept the data and then I'm gonna paste it in.
It's gonna accept the data and then I'm gonna paste it in without this function of course. So I'm gonna replace response to data with just data. So let's do this and then from here, if we get a response, we're just gonna call setModal with the response data and then I'm gonna export that new function setModal so that we can reuse it on other places. So in our layout file, I'm going to import
Watching Page Props1:47
that we can reuse it on other places. So in our layout file, I'm going to import that new method setModal. And then maybe below here we are gonna watch the pageProps. So if there is a modal object on the pageProps, we are gonna set it with this new setModal method. So let's start by resolving the pageProps page equals usePage, and we need to import that. And then I'm gonna need a watcher. So I'm gonna import watch. And let's watch.
And then I'm gonna need a watcher. So I'm gonna import watch. And let's watch. Uh, for the pageProps _modal. So here we are receiving our model and I want to execute this immediately. So immediate equals true. So when this layout is mounted, we want to execute this callback. Alright, let's dump it out for now.
to execute this callback. Alright, let's dump it out for now. So Lock model and let's hit save. And also just one little tip, you don't want to do this, you don't want to call use Page here in this callback because that's gonna cause memory leaks. Let's go to the browser, hit refresh. And here you can see our model object again. And there are two things that we need to fix first. This model is wrapped in some kind of proxy
And there are two things that we need to fix first. This model is wrapped in some kind of proxy and we don't want to use that. So that's one thing we need to take care of. And then we're actually loading the wrong component. So here we are loading the edit page, but we want to load the edit modal. So let's go to the UserController. And here this request, onceModal that one I'm gonna remove.
And here this request, once modal that one I'm gonna remove. And for now we are just gonna always return this editModal. Alright then in our layout file, we want to use our new setModal method, but actually only if there is a modal. So if there is a modal, we're gonna call setModal. And I'm going to use this syntax to create a new object with our modalProps. And that should get rid of the proxy.
with our modal props. And that should get rid of the proxy. So let's go to use modal again. And in here, let's log it out one more time to see what we get. Let's go to the browser, let's hit refresh. And here we can already see our model and we now have a plain object instead of a proxy. So let's hit cancel. That seems to work, but we're still on the edit page.
Redirecting on Modal Close4:20
So let's hit cancel. That seems to work, but we're still on the edit page. And let's try again, updating the user. 1, 2, 3, update. And yeah, did update, yeah, we have 1, 2, 3, but we still have the modal opened. And again, we are on this edit route. So let's fix that. Let's go back into our code. And what we wanna do is in useModal, let's remove this lock. When we reset the modal, when we set modalValue to, no,
let's remove this lock. When we reset the modal, when we set modal value to, no, just before this we want to redirect back to the base URL. So let's see, uh, if we have a base URL on the mod, so base URL, and again this might be empty and if that base URL is not the same as our current URL, the current uh, URL of the window. So window.location.href. In that case we want to visit, uh, with the router,
So window.location href. In that case we want to visit, uh, with the router, we want to visit the base URL. And then we need to import the router from the Inertia library. So import a router from inertia. So let's go over that again. Before we remove the modal from the do, we're gonna check if we have a base URL on the mod object. And if that's not the same as the current URL, then we want
we're gonna check if we have a base URL on the mod object. And if that's not the same as the current URL, then we want to visit that base URL. So let's see if that works. Let's refresh, let's hit cancel. And then you can see that we are redirected back to the User page. So let's reload this one. Let's try to click on edit. You can see that we are navigating to the edit page, but when I hit the back button of the browser,
You can see that we are navigating to the edit page, but when I hits the back button of the browser, then I'm redirected back to the users page again to the index page. But we still have this model here, so we need to go back to our watcher in the layout file. And here we want to check if we don't have a modal, so no modal, then we want to close the old one if it's there. So also in this close method we need
to close the old one if it's there. So also in this close method we need to check if we actually have a modal. So if we have a modal, then we are gonna set the show value to false and then eventually this reset method will be called. So let's see if that works. We're now on the users page, click on edit, we have our nice modal that's hit back and that seems to work.
Supporting Non-Index Backgrounds7:06
we have our nice modal that's hit back and that seems to work. Now let's go to the profile of the User. And here we also have that added link. And if I click that one that I'm actually redirected to this edit route, which is good, I also see the modal, but we're still having the index page below the modal and it would be nice if we actually could stay on that profile. So from here, if I click on edit,
on that profile. So from here, if I click on edit, it would be nice if I just has this, have this profile as a background with a model on top of it. So we need some kind of way to pass the base URL from the front end as well. And actually that already happens. So if you go to the network inspector, and if I click on edit, then I can check out the request headers.
and if I click on edit, then I can check out the request headers. And here you can see the referrer is already set to the User page, to the User profile page. And it also happens on the index page. So if I'm here and I click on edit, then you can see that this header is set to the index page. So let's go to our modal macro, let's go to AppServiceProvider, and then I want this base URL more
to AppServiceProvider, and then I want this base URL more or less act as a fallback. So by default we are gonna set baseUrl to that header. And if it doesn't exist, if it's null, if it, if it's empty, then we're going to fall back to our baseUrl that we're passing from the controller. So let's go to fire folks and let's see if that works. And I actually already know that it doesn't work.
So let's go to fire folks and let's see if that works. And I actually already know that it doesn't work. But let's show it to you. Let's go to the user profile, let's clear this out. And then when I hit edit, you can see a bunch of errors. And maybe the most important one is this one, we have a Ziggy error that takes care of the routes on the front end user is required for the routes. So whereas our user parameter,
Fixing Route Model Binding9:10
is required for the routes. So whereas our user parameter, and you might remember that I've shown you the middleware in a previous episode, let's dump it out once again. Whoops, like this. Let's refresh. And we are looking for this specific middleware substituteBindings. Let's grab it and let's introduce it here. I'm gonna resolve it from the container
Let's grab it and let's introduce it here. I'm gonna resolve it from the container and I'll show you what it does in a minute. So let's grab it and let's open it here. You can see that this middleware cost substitute bindings and implicit bindings on the router. And what that does is actually replace the user parameter. So that's mostly the user key, the id. It's gonna replace it with the real Eloquent model.
So that's mostly the user key, the id. It's gonna replace it with the real Eloquent model. So if we have something like, uh, user/1/edit, then if you call something like request routes and then id or maybe user, then at this point it's just gonna return 1. But this middleware replaces this 1 with the actual Eloquent model. So something like this, that's
with the actual Eloquent model. So something like this, that's how our controller is built. We go to UserController and we check out the show page. Then we don't expect an ID here, we don't expect an integer of one, but we expect a User model. So that happens in that middleware. Let's check it out one more time. This is like a typical Laravel middleware. It has this one handle method that's accepting the request.
This is like a typical Laravel middleware. It has this one handle method that's accepting the $request and then a $next closure. And actually we don't care too much about $next because it's not executed within a stack. We just want to call this middleware, uh, on its own. So in our AppServiceProvider, let's call handle, uh, on this, uh, on this middleware, uh, we kind of pass it our $request and that $next closure we don't really care about.
of pass it our request and that next closure we don't really care about. So we just gonna give it a dummy closure like this. And then I don't want the middleware anymore. Let's get rid of it here as well. And actually this needs to be executed before we run the route, of course. So more like this. Let's see if it works. Uh, let's hit refresh. So now that we have a new request, it's not going to use
Uh, let's hit refresh. So now that we have a new request, it's not going to use that header, but it's gonna use our fallback because this is a fresh request. Gonna hit cancel. Let's go to the User profile. And in this case it should use that header. So let's hit edit and that seems to work, so that's really great. Uh, let's see if cancel works. Yeah, that seems to work. We're also redirect back to the right URL,
Uh, let's see if cancel works. Yeah, that seems to work. We're also redirect back to the right URL, so not to the index route. Let's see if update works. 1, 2, 3, update. And that still doesn't work. So that's what we are going to fix in the next episode.
