Laravel InertiaJS & Vue 3 toast notifications

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if we go in the browser refresh hit the submit button the notification is added at the top but the element being animated is at the bottom what the hell is going on well the reason why this happens is because here I have a default laravel Breeze installation with inertia and vue.js what I want to do is add those notifications you know those kinds of notifications that appear in the top right corner of the screen you see them for a couple of seconds and then they disappear now because this is an app y feature so any page should be able to show this type of notifications The View component we're going to build will be placed in a layout file specifically the authenticated layout component to get things going I'll copy and paste those examples from flow byte which is an open source Tailwind component Library I'll go here to default host hit copy to grab the code snippet go back to our component inside the main div paste it in hit save and here's our toast message however as you can see it's incorrectly positioned it should always appear in the top right corner of the screen to do that we can add the fixed class and then do top let's say four to have some spacing and write four another thing we should also do is increase the Z index to make sure the element Stacks over any other element in the page so we'll do something like C50 now the toast message is correctly positioned but if I am to add another one so if I copy and paste this the elements will stack over each other what we can do is add a parent element so I'll wrap this within a div and turn this one into a fixed element so I'll grab these classes go here paste them in and now if we add another toast message it will appear under the first one let's also add some spacing so space y four let's say and let's also grab the classes controlling the width so I'll grab these paste them here let's remove this one let's delete the ID because we won't need it and now if we add more messages they will appear under each other which is what we wanted now that we're done with the visual part let's grab this and turn it into a view component so I'll grab this go to resources.js components create a new file called toast list.view will have script setup and then template paste that in go back to the authenticated layout and replace this with toast list let's import a component we'll do import those lists from at component slash toastlist.view and here it is if we go inside the toastless component we can take this one further by extracting a toast list item component we'll grab the markup corresponding to a single toast notification go to our components directory create a new file called toast list item Dot View will have script setup template and I'll paste that in back to our toast lists we'll import the new component so we'll do import toast list item from that slash components slash toastlist item Dot View and then we'll use it here there we go however right now the toast list item component can only be used to show this set yourself free message we need to be able to customize this and we can do that using props we'll go here and Define the props we'll do const props equals Define props and we'll have message which will be a string then we can take this and replace it with props.message back to our toastless component we can go ahead and pass in the message prop and here it is let's add another one [Music] and another one however continuing to copy and paste this toast list item component is not a good way going forward we need a more data-driven approach what we can do is store the toast messages inside an array and then Loop through it so I'll grab the messages go inside script setup and do const items equals ref of array let's import ref from View and here we'll have an array of objects with a message key so I'll paste those in and turn them into objects then down here we'll remove these two and loop through the array so we'll do V4 item index in items we'll turn this into a dynamic prop and do item Dot message let's also add the key and now we still have the same thing but we can add new toast messages in a more data driven way moving on let's see how we can remove a notification now we have this x button right here which is inside the toast list item component but the data controlling whether or not this component should be rendered is inside the parent component now the way a child component communicates with a parent component in view is true events so let's go back to our child component and do const emit equals Define emits and we'll have remove now whenever the user clicks on the x button so on click will emit that event so we'll do emit remove back to our parent component we'll listen to that event so we'll do it remove and we'll call a remove function and pass it the current index let's define the remove function which will receive the index and we'll use that to remove the item from the array so we'll do items.value splice will pass it the index and then the number of items we want to remove which is one now if I refresh and click on the x button the notification is removed if we think about adding a notification to our items array one use case would be when a form is submitted and we flash some session data on the server so let's close the browser for a moment open our dashboard page component and add the dummy form so I'll go here and say form on submit prevent called the submit function and inside the form we'll just have a button saying submit now inside script setup we'll create a form using the inertia form helper so we'll do const form equals use form and we'll pass it on empty object and then for the submit function we'll just take that form and post it to a test endpoint then I'll open the web routes file to add the new endpoint so we'll do route post slash test function and this will just redirect back so we'll do return redirect back but while doing so we'll also flash some session data using with need to pass a key let's say toast and a message toast endpoint however another thing we need to do is make sure we share this toast session data with our front end and we can do that by going inside the handle inertia request middleware scroll down to the share function and add a new key to this array let's say toast and we'll use session to grab the session data now if we go in the browser and refresh open up the dev tools inspect the props we see we have toast no but once we submit the form the value changes to toast endpoint what we need to do now is add this toast value to our array of items we could do that by watching the props for changes but that won't work that good because sometimes the message we get back might be the same a more reliable way is to listen to the inertia finish event so let's go back to our toastless component and add an event listener we'll do inertia on finish we'll have a callback and in this callback we'll check the page props and if we have a toast message we'll add it to the items array so let's Import in our share from inertia let's use the use page composable to grab the props so we'll do const page equals use page and we'll import this from inertia and then here we'll basically do if page dot props dot value toast so if we have a toast we'll do items value and shift because we want to push the item at the start of the array message equals page props value toast let's go in the browser refresh hit the submit button and here they are we can of course remove them submit again and so on however one important thing to keep in mind is that pretty much any time we add an event listener we need to make sure we also remove it when we no longer need it otherwise we risk ending up with a dozen of event listeners that do the same thing now with inertia whenever you register an event listener the result you get back is a callback you can execute whenever you want to remove that event listener so we can start this in a variable we'll do remove finish event listener and then whenever the component is unmounted we'll execute that function so we'll do remove finish event listener Let's test it out refresh submit and everything is still working so we've tackled the use case where an inertia request is made and the server returns a toast message but what about adding those notifications programmatically for example when making a regular access request let's say we go to our dashboard page component add a new button that will add toast and when this button is clicked it will call and add toast function let's define a function and here what I basically want to do is communicate with our toastless component and tell it to add a new item inside the array however as you may know direct cross component communication is not possible in view we need something in the middle to handle the state that something can either be a penis store if you use Pina for State Management or a basic view composable we'll go with the second approach I'll go ahead and create a new directory and we'll call this one stores and inside it will have a file called dose.js this file will simply export a reactive object so it will do export default reactive and we'll import this from View and inside it will have an items key which will be our array of those notifications let's go ahead and grab it from here paste it in and then instead of having this ref right here we'll import toast from Earth slash store slash toast and wherever we have items we'll use the toast object so here we'll have toast dot items and the same thing here if we go in the browser refresh hit the submit button click the x button everything still works the same but we now have a store with which any component can communicate with that means if I go to my dashboard page component and import the toaster from Earth slash store slash toast inside the add dose function we can do toast.items on shift and push a new object hello from dashboard let's go in the browser click the add toast button and here it is however now that we have an object we can add methods to it so here we can do add and we'll receive a toast and we can basically do this items on shift toast and of course we can also have a remove function which will take in an index and we'll do this item splice index of one then we can go back to our dashboard page component and say toast add go to our toast list component and say toast add and here we'll say toast remove index this is not only a lot cleaner but we've now centralized the way we mutate our items array moving on there are two more things we need to do the first one is to add some animations while the second one is to make the toes notifications go away after a couple of seconds to add the animations we'll go back to our toastless component and make use of the built-in transition group component this works just the same as a regular transition but with more elements so we'll convert this div into a transition group and we'll pass it a tag prop equal to div such that view renders this component as a div element then we'll have an enter from class prop enter active class prop leave active class prop and leave to class prop the enter from class prop represents the starting point of our toast notification when is added to the Dom so it should start outside of the screen to do that here we can add translate X4 and let's also say opacity 0. and the same thing should happen when the element leaves at all now while it's doing that it should do it in a duration of let's say 500 milliseconds if we go in the browser refresh hit the submit button the notification is added at the top but the element being animated is at the bottom what the hell is going on well the reason why this happens is because an array index is a horrible Choice as a component key this key should be unique to the item in the loop but instead we are using the index which represents the current position of the item in the array but this is not unique as it changes when we add another item at the start of the array so what happens here is that view reuses the existing Dom elements and only adds a new element at the bottom and that is why this element is being animated to fix this we just need a better key we don't have an ID but what we can use instead is a symbol a symbol is a built-in object whose Constructor returns a simple primitive that's guaranteed to be unique so back to our toast store when we add a new toast we could also add a key here that is a symbol and then use the spread operator to get the rest of the properties back to our toastless component instead of using the indexes key we can just say item dot key now if we refresh and hit the submit button the toast notification is added and animated at the top which is what we wanted same thing when we remove the notifications let's go ahead and focus on the other thing which is automatically removing the toast notifications after a couple of seconds to do that we can go inside our toast list item component and on the on mounted hook so when this component is mounted we'll start a timer using so we'll use set timeout and we'll emit the remove event after let's say two seconds I'll save and let's also remove the toast items from inside the array and now we can just add a new toast and the elements will disappear after two seconds of course we can also customize that we can go to our toast list item component and send this as a prop so here we can do duration and it's of type number and we'll set default to 2000. and then here we'll use props dot duration now if we want to go to our toast list component we can pass in a duration prop which we can set to let's say 1 000 milliseconds and there we go to recap we have a toaster with which any component or composable can communicate with and this allows us to programmatically add in notifications using the add method and we also have an inertia event listener here inside the toastless component that checks for toast messages whenever we make an inertia request and that was it code Snippets are on toll pad if you enjoyed this video don't forget to like it share it subscribe click the Bell button all that good stuff bye
Info
Channel: cdruc
Views: 12,704
Rating: undefined out of 5
Keywords: vuejs, vue, laravel, inertiajs, tailwindcss, toast notifications
Id: bIZBNYFXcKU
Channel Id: undefined
Length: 18min 50sec (1130 seconds)
Published: Fri Nov 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.