00:01
Inertia released version 2.0, and it was mostly a feature release rather than a breaking change release. In fact, I don't believe we have any breaking changes inside of our application,
00:09
just one minor change that we need to do. And the features that are brought along with it were things like polling, infinite scroll, prefetching, and deferred props.
00:19
So in this module, we're gonna update our project to use Inertia 2.0, and we'll go ahead and update all of the other DOMs.js dependencies that have changed since we started this project.
00:27
Then we'll walk through each of the new features and see exactly how they work. Let's first discuss one change with Inertia 2.0 that's not all that noticeable.
00:36
And though it may not be that big of a change, it does have big ramifications in how our application actually works whenever we send requests out to our server. So let's say that we have our browser here,
00:45
and then we have our server up here. A user might click a button inside of our browser that then sends a request up to our server.
00:53
In Inertia 1.0, before the user could click this button again, they had to wait for that response to come back because Inertia's flow was synchronous in that manner.
01:02
It needed to send one request and get one response back at a time. With Inertia 2.0, however, these requests are now asynchronously handled.
01:11
So the user can click the button, and before they get the response back, go ahead and click the button again and again, and Inertia will now handle the responses
01:21
as they come back appropriately, essentially meaning that Inertia is able to handle more than one request at a time now in Inertia 2.0, where that was not the case in 1.0. All right, so let's go ahead and start
01:31
by getting into our terminal here. And there's a package that I like to use to simplify installing NPM updates called npm-check-updates. So let's install that globally.
01:41
So we'll do npm i -g npm-check-updates. Go ahead and have that installed globally, and then we can clear our browser out. This should now be globally available to us
01:50
as either npm-check-updates, or there is an abbreviated version called ncu. This command will take the directory that we're currently in, check for its package.json,
01:59
and check it against potential updates that it could have. And we can enable an interactive version of this as well by providing -i as the interactive flag. Go ahead and hit Enter there,
02:09
and it's gonna scan our package.json and give us back the updates that we have available. So we can see that for our AdonisJS core package,
02:16
we are at version 6.9.1 at present, but the latest available is 6.17.2. So if we did not want to update,
02:25
we could use the arrow keys to go down to that package. The current package that we're at is noted by this little arrow icon right there, and then use the space bar to either deselect it or reselect it. For the most part,
02:35
we can go ahead and update everything here. The only exception is going to be TailwindCSS. At present, I don't believe Shod CM view's updated
02:44
to support TailwindCSS version 4. There seems to be some availability difference in TailwindCSS 4 when using the add apply directive inside of style tags with Vue.js.
02:54
So for now, we'll just take these two TailwindCSS packages and omit them from our update. When we hit Enter now, this is gonna go ahead and commit it to our package.json
03:04
and ask us if we want to install. We can hit Y for yes and for no. Let's go ahead and hit Y, although I believe this is going to fail
03:12
due to an ESLint peer dependency issue. All right, and sure enough, there it is. So NPM tends to be rather strict with its peer dependency versions.
03:21
And I've even tried installing the exact ESLint version and still get the peer dependency conflict here. One way that you can resolve this is just to have NPM go back through
03:31
and re-resolve those peer dependencies with NPM update. We can go ahead and run that in our terminal. And all right, looks like that worked successfully. That just kind of went back through our package.json file
03:41
and updated everything to the latest available version within the range that we have defined inside of our package.json file.
03:48
So for example, if we go into our package.json file inside of our text editor, scroll on down to our dependencies, doesn't really matter which, most of these versions are going to be prefixed
03:58
with this little caret character. And essentially what that caret does is it provides the ranges anything from 10.4.20 here for say auto-prefixer,
04:07
all the way up through just below version 11. So it will stay on the same major version, but it won't care about these last two ticks.
04:15
And it also will not go below the version specified here. Cool, so we can go ahead and close both of those back out as they should be good to go. And as I mentioned before, there really aren't any major breaking changes
04:25
that impact our project. There are other breaking changes that don't impact our project. Like for example, view to support was dropped,
04:32
the router replace method now makes client side page visits. A number of Svelte adapter changes, including dropping support for version three and impartial reloads inside of your application
04:42
are now asynchronous to match with the overall async flow of Inertia 2.0. The one thing that we do want to change inside of our project, however,
04:50
comes in play with the AdonisJS Inertia adapter. This adapter, if we go ahead and jump into the Inertia configuration, is now automatically including our errors
05:00
within our shared data. So we don't need to define this error object here. Furthermore, it's also normalizing this for us behind the scenes from an array of errors
05:10
per input field key to just a string. So we can go ahead and get rid of that altogether now. And in addition, the errors object that they provide
05:19
includes our errors bag when exceptions are thrown. And the errors provided via that tag are now an if else. If there's an errors bag, it's going to provide that.
05:28
Otherwise it will provide the input errors to us. So we can go ahead and get rid of our exceptions as well. And we still have our overall messages that we're providing here,
05:36
should we need specific access to just the errors bag. So that trims down our shared data there slightly. We can go and give that a save.
05:44
And there's a few spots that we actually want to update to reflect that change. So let's go ahead and dive into our Inertia
05:51
down to our pages and our auth login page. Here we have that exceptions object that we were previously sharing
05:59
via our shared data being provided. We can now go ahead and switch this to just reading directly from the errors shared data that the AdonisJS Inertia adapter
06:08
is automatically providing to us. In turn, that also means that we can read our alert from that errors object rather than our exceptions.
06:16
Just kind of normalizing everything for us there. Okay, cool. On top of that, if you previously had your, let's see your form input component here,
06:25
accepting in a string array as its error, you'll want to normalize that to now just a string. And then again, we're also now using view 3.5. So you're free to make any of those updates
06:35
that you wish there as well. Okay, cool. Let's go ahead and get back into our browser then and give it a refresh to make sure everything's working okay. And so far it looks like it. Awesome.
06:44
We can go ahead and dive into some of our courses, ensure that this is working okay. And it looks like it. Sweet.
06:52
Ensure our delete configuration's coming up here and that looks good too. Our difficulties, make sure that the drag and drop is going okay. That looks good. Let's check our organization dropdown.
07:02
That looks fine as well. We can go into the edit, update. Our toasts are working. Let's go into our profile settings. That looks good.
07:11
Go ahead and hit update there. The account settings, that looks good as well. We won't go through either of those. We'll assume that they're okay. Our organization settings, that looks good there too.
07:21
Now, while we're here, there is one issue that we've had in our project all along that just kind of escaped my proximity of what to look out for.
07:29
Joel's notified me that if we go ahead and open up, let's say our courses, dive into one of these and open up our project inside of a different tab.
07:37
And let's say that we go into localhost3333/courses and we switch to a different organization. Since we're now inside of a different organization
07:47
in this tab, then we are in our original tab. If we try to make a change here, does this work? Save that. We're gonna end up getting a row not found
07:56
because this is trying to work with that other course and it's running into an issue. Trying to find this module inside of that course. And this happens because our active organization cookie
08:06
is shared across all of our browser tab instances for our application. This would not be an issue had we had the active organization ID inside of our URL. However, there's alternatives that we can do
08:16
to keep that active organization ID outside of our URL. And that could be something as simple as jumping into our application layout and watching the tab or focus.
08:26
So unmounted because we don't want this to be added via our server side rendering, but rather just client side. We'll add an event listener to the window or the focus event.
08:36
On focus, we want to apply a function which we can call on focus. We don't need the event for that. And instead we can directly just reach
08:43
for InertiaVue 3's router to send a get request to re-update the active organization to the one that's active inside of this tab.
08:52
So props, organization, ID, just like so. And then bind that on focus handler to the focus event.
09:01
And then of course on unmounted, we want to remove that listener. So window.removeEventListener, focus for the on focus function.
09:10
So obviously there's a bunch of different ways that you can do this. You could also use the broadcast channel to alert the other tabs that the active organization was changed and then display something like a modal
09:19
to allow the user to reactivate the active organization and that's, or return back home, something of the sort. But in simple form, this will work just fine. So let's go ahead and jump back into our browser
09:29
and let's give this another test. So let's go ahead and close out our secondary tab, switch back to my first organization, which has our courses, and walk through that exact same flow again.
09:39
So we'll get my first organization with course test two here and open up a new tab, pointing this to localhost 3333/courses. We'll go ahead and switch on over
09:49
to my second organization in this tab, jump back over to our original tab. And with that set, with us just jumping back over to this tab,
09:58
our active organization should now be my first organization again. So if we dive back into this course, add a lesson, does this work? And it sure does.
10:08
We jump back over now to our other tab. We're now back at my second organization. So if we add a course, it will work just fine and it will apply to that same organization.
10:18
Obviously, as you saw, the downside to this approach is that we are now redirected back to our courses index page automatically. And there's actually a really easy change that we can do to keep the user where they are on the page,
10:28
as well as any of the adjustments that they've made on the page as well. And that's really just taking inertia out of the equation on this particular request.
10:37
So we'll switch this from a router.get to just a fetch to that same URL. The default method there should be a get. We can remove our router import. And then let's go and jump
10:47
into our organization controller, grab our request out of our HTTP context, and let's check and see whether or not this was sent with inertia.
10:56
So if not request header X inertia, then we can go ahead and just return response.no content
11:06
to send back a 204. Now, if we jump back into our browser, let's give that a test once more. So let's jump into our course test two, but let's take this a step further.
11:14
Let's jump into our edit panel of does this work, add in a yes with an exclamation point, and then let's go ahead and jump back over to our other tab.
11:23
This has now set my second organization as our active org. We can again verify that by jumping into here, adding in a test two, adding that course.
11:32
We can see that that was added to my second organization. Jump back over now to our original tab and look at that. Does this work still is there along with our yes edit.
11:42
If we update this, it applies successfully, making that a nice fluid transition between our first and second organization between our two different browser tabs.