Notificaciones con SweetAlert2 desde Livewire cover image

Notificaciones con SweetAlert2 desde Livewire

Reny Ramos • November 1, 2020

laravel livewire livewirev1 sweetalert2 notifications programming

En ocasiones cuando se trabaja ya sea tanto con Librerías o Frameworks de JS como con Livewire, se requiere de darle algún feedback al usuario para informar del estatus del proceso, demasiada magia es malo.

Lo que se desea con las notificaciones, en teoría, es mostrar cierta información de cierta forma, y dependiendo de la información y contexto cambiará la notificación y sus atributos, ya que el back solo enviará la información, nos centraremos primero en el front.

Primero crearemos una vista, yo prefiero trabajar todo con componentes, donde estará la lógica de las notificaciones views/components/notify.blade.php aprovecharemos y tomaremos prestado uno de los ejemplos que están en la página de sweetalert2 para toast y le haremos algunas modificaciones que explicare a continuacion.

<script>
   const ToastAlert = (type, title, text = '', timeout = 4000, position= 'top-end') => {
       const Toast = Swal.mixin({
           toast: true,
           position: position,
           showConfirmButton: false,
           timer: timeout,
           didOpen: toast => {
               toast.addEventListener('mouseenter', Swal.stopTimer)
               toast.addEventListener('mouseleave', Swal.resumeTimer)
           }
       })
       Toast.fire({
           icon: type,
           title: title,
           text: text
       })
   }
   this.livewire.on('notify:toast', data => {
       ToastAlert(data.type, data.title, data.text, data.timeout, data.position)
   })
</script>

Toda la lógica de la notificación estará dentro de la Function expression llamada ToastAlert, quien aceptara los datos de configuración en el orden dado (sólo type y title son obligatorios), incluso se puede probar desde el navegador. Al final se enlaza un evento que se disparara desde Livewire el cual llamará a la función de la notificación.

Lo único que falta es emitir el evento desde Livewire, lo cual se hace desde el componente Livewire con $this->emit() pasando el nombre del evento y las variables, como se ve a continuación.

$this->emit('notify:toast', [
    'type'  => 'success',
    'title' => trans('notifications.user.created),
]);

Por último incluimos la librería JS(JavaScript) de sweetalert y el component, o vista con un include, al final del body, suponiendo que se tiene un layout en layout/app y simplificando un poco, el app.blade.php debería quedar parecido a lo siguiente.

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<link href="{{ asset('css/app.min.css') }}" rel="stylesheet">
   @stack('styles')
   @livewireStyles
</head>
<body>
   <div>
   .
   .
   .
   </div>
   <script src="{{ asset('js/app.min.js') }}"></script>
   <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
   @yield('scripts')
   @livewireScripts
   @component('components.notify)
   @endcomponent
</body>
</html>

Como paso extra podemos mejorar un poco ese codigo JS JavaScript, para evitar declarar la const Toast y encadenar directamente las acciones de la siguiente forma.

<script>
   const ToastAlert = (type, title, text = '', timeout = 4000, position= 'top-end') => {
       Swal.mixin({
           toast: true,
           position: position,
           showConfirmButton: false,
           timer: timeout,
           didOpen: toast => {
               toast.addEventListener('mouseenter', Swal.stopTimer);
               toast.addEventListener('mouseleave', Swal.resumeTimer);
           }
       }).fire({
           icon: type,
           title: title,
           text: text
       });
   }
   this.livewire.on('notify:toast', data => {
       ToastAlert(data.type, data.title, data.text, data.timeout, data.position);
   })
</script>

Y eso es todo, se crea un function expression por cada tipo de notificación que se desee incluir, se pueden crear todas en el mismo archivo o en diferentes y agregarlos según sea necesario y a cada una se llamara con su propio evento.