'How do I pass data in $router.push in Vue.js?

I am creating an alert component for a CRUD app using Vue.js. I want a message to be passed to another component once data has been saved. Currently I am trying to pass this data in $router.push like this this.$router.push({path: '/', query: {alert: 'Customer Added'}}) Then access this data in another component. However this is not working as expected, instead the data is passed into the url.

This is the component which saves the data, Add.vue

<template>
<div class="add container">
<Alert v-if="alert" v-bind:message="alert" />
<h1 class="page-header">Add Customer</h1>
<form v-on:submit="addCustomer">
    <div class="well">
        <h4>Customer Info</h4>
        <div class="form-group">
            <label>First Name</label>
            <input type="text" class="form-control" placeholder="First Name" 
            v-model="customer.first_name">
        </div>
        <div class="form-group">
            <label>Last Name</label>
            <input type="text" class="form-control" placeholder="Last Name" 
            v-model="customer.last_name">
        </div>
    </div>
    <div class="well">
        <h4>Customer Contact</h4>
        <div class="form-group">
            <label>Email</label>
            <input type="text" class="form-control" placeholder="Email" v-model="customer.email">
        </div>
        <div class="form-group">
            <label>Phone</label>
            <input type="text" class="form-control" placeholder="Phone" v-model="customer.phone">
        </div>
    </div>

    <div class="well">
        <h4>Customer Location</h4>
        <div class="form-group">
            <label>Address</label>
            <input type="text" class="form-control" placeholder="Address" v-model="customer.address">
        </div>
        <div class="form-group">
            <label>City</label>
            <input type="text" class="form-control" placeholder="City" v-model="customer.city">
        </div>
        <div class="form-group">
            <label>State</label>
            <input type="text" class="form-control" placeholder="State" v-model="customer.state">
        </div>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</template>

<script>
import Alert from './Alert'
export default {
name: 'add',
data () {
    return {
    customer: {},
    alert:''
    }
},
methods: {
    addCustomer(e){
        if(!this.customer.first_name || !this.customer.last_name || 
!this.customer.email){
            this.alert = 'Please fill in all required fields';
        } else {
            let newCustomer = {
                first_name: this.customer.first_name,
                last_name: this.customer.last_name,
                phone: this.customer.phone,
                email: this.customer.email,
                address: this.customer.address,
                city: this.customer.city,
                state: this.customer.state
            }
            this.$http.post('http://slimapp.dev/api/customer/add', 
            newCustomer)
                .then(function(response){
                    this.$router.push({path: '/', query: {alert: 'Customer 
            Added'}})

                });
            e.preventDefault();
            }
            e.preventDefault();
            }
            },
            components: {
             Alert
            }
            }
            </script>

            <!-- Add "scoped" attribute to limit CSS to this component only 
            -->
            <style scoped>
            </style>

This the alert component, Alert.vue

<template>
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span></button>
{{message}}
</div>
</template>

<script>
export default {
name: 'alert',
props: ['message'],
data () {
return {

}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

And this is the component where the alert is to be viewed, Customers.vue

<template>
<div class="customers container">
<Alert v-if="alert" v-bind:message="alert" />
<h1 class="page-header">Manage Customers</h1>
<table class="table table-striped">
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Email</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="customer in customers">
      <td>{{customer.first_name}}</td>
      <td>{{customer.last_name}}</td>
      <td>{{customer.email}}</td>
      <td></td></tr>
  </tbody>
</table>

</div>
</template>

<script>
import Alert from './Alert';

export default {
name: 'customers',
data () {
return {

  customers: [],
  alert: ''

 }
},

methods: {
fetchCustomers(){
  this.$http.get('http://slimapp.dev/api/customers')
    .then(function(response){

      this.customers = (response.body); 
    });
  }
 },
created: function(){
 if (this.$route.params.alert) {
   this.alert = $route.params.alert
 }
 this.fetchCustomers();
},
updated: function(){
this.fetchCustomers();
},
components: {
  Alert
  }
}

How do I solve this?



Solution 1:[1]

It is not possible to pass data through vue-router the way you want to. You only can pass parameters like this:

Route definition:

{ path: '/products/:id/edit', name: 'products.edit', component: ProductForm },

And then you can get the parameter with this.$route.params.id

Or you can do:

this.$router.push({name: 'products.index', params: { id: 1 }})

I suggest you to add a GET parameter like ?success=true or show an alert with sweetalert for example before pushing the new route.

Solution 2:[2]

A weird solution is to set the value to store/local_storage and retrieve and destroy it from the store/local_storage when the destination page loads.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marcello B.
Solution 2 Harcop Toluwap