Redirecting with messages in laravel with vue.js

Viewed 2905

I have a button that deletes the record in table, and it works on purpose. But I need to add a message after deleting (not alert). When I was doing that in Laravel only, it worked perfectly. But now I have Vue.js in my project and it doesn't work.

It should return a green box that says 'successfully deleted record', when I write the same code in Laravel, it was working amazing. But with Vue.js, it doesn't work.

My blade file, it extends vue component. The message is before that in code.

<body>
        <div id="app">
            <div class="container">
                @if(session('alert_delete'))
                <div class="alert alert-success">
                    {{ session('alert_delete') }}
                </div>
                @endif

                <students>

                </students>
            </div>
        </div>


        <script src="{{asset('js/app.js')}}">

        </script>

My Controller

public function destroy($id)
    {
        $student = Student::findOrFail($id);

        $student->delete();

        return redirect('/')->with('alert_delete', 'Selected query is deleted successfully.');
    }

Vue method to delete record

deleteStudent(id){
                axios.delete(`api/student/`+id)
                location.reload();
            },

I was also using that to show validation errors. But now, it doesn't even show simple success message.

It's reloading the page by location.reload(); function on Vue method. But it doesn't work when I try to redirect from controller.

2 Answers

Ajax requests dont return with session data so you have to make a response alternative for ajax request. So your code should look something like the following:

Controller

public function destroy($id)
{
    $student = Student::findOrFail($id);

    $student->delete();

    if (\request()->wantsJson()) {
        return response()->json([
            'alert_delete' => 'Selected query is deleted successfully.'
        ]);
    }

    return redirect('/')->with('alert_delete', 'Selected query is deleted successfully.');
}

Vue

deleteStudent(id){
    axios.delete(`api/student/`+id).then(response => {
       
       // Message will now be available here:
       response.data.alert_delete

       // You can now display the message to your users using JS notification
       // libraries like SweetAlert2 or toastr.

       // You don't really need this
       location.reload();
    })
},

or

// Set this in data() method of your vue component.
// alert: null

deleteStudent(id){
    axios.delete(`api/student/`+id).then(response => {
       
       // Message will now be available here:
       response.data.alert_delete

       this.alert = response.data.alert_delete

       // You don't really need this
       location.reload();
    })
},

And still in the same vue component, display the message like so:

<div v-if="alert" class="alert alert-success" v-text="alert"></div>

// You can use a close button to set "alert" back to null if the 
// users wants to clear alert.

So with the above code, you can display notifications or alert when making ajax request and session when making a regular HTTP request...

The message you've used relies on data being flashed to the session so you'd need to use a web route to handle the delete, flash the message to the session and redirect back to the original page.

If you want to raise a message after handling the delete with an axios request you'd need to place an element in the template that reacts to an event raised by the axios request.

deleteStudent(id){
    axios.delete(`api/student/`+id)
        .then(response => {
            trigger_message();
        });
},

Trigger alert would need to raise an event that your message element subscribes to.

The easiest way would be to wrap the entire content in a Vue component and use a v-if on the message element

Vue Component

<template>
    <div v-if="deleted" class="alert alert-success">
        Student {{ student.id }} Deleted
    </div>

    <student @click="deleteStudent"></student>

</template>
<script>
    data () {
        return {
            deleted: false
        }
    },
    methods: {
        deleteStudent(){
            axios.delete(`api/student/`+id)
                .then(response => {
                    this.deleted = true;
                });
        },
    },
</script>

That should be a good starting point. There's more you might want to do with your alert like set a timed fade-out on it. Bootstrap-Vue's Alert component is a great option for this and the documentation has some excellent examples to get you started.

Related