Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue: display response from form submit on another page

I have a <form> in vue. I send that form to server, get a JSON response, print it to console. It works fine.

However I need to take that JSON response and display it on another page. For instance, I have two .vue files: GetAnimal.vue that has the form and retrieves the animal data from an API and a DisplayAnimal.vue that displays animal's data. I need to direct the response animal data from GetAnimal.vue to DisplayAnimal.vue.

GetAnimal.vue:

<template>
 <form v-on:submit.prevent="getAnimal()">
  <textarea v-model = "animal"
      name = "animal" type="animal" id = "animal"
      placeholder="Enter your animal here">
  </textarea>

  <button class = "custom-button dark-button"
      type="submit">Get animal</button>
 </form>
</template>
<script>
    import axios from 'axios';

    export default {
        name: 'App',
        data: function() {
            return {
                info: '',
                animal: ''
            }
        },
        methods:  {
            getAnimal: function()  {
                 axios
                    .get('http://localhost:8088/animalsapi?animal=' + this.animal)
                    .then(response => (this.info = response.data));
                 console.log(this.info);
            }
        }
    }
</script>

response: retrieves a JSON with animal data, say like this:

{
"fur-color": "yellow",
"population": 51000,
"isExtinct": false,
"isDomesticated": true
}

and I now want to give that JSON to a DisplayAnimal.vue at /viewanimal endpoint:

DisplayAnimal.vue:

<template>
  <div>
    <p>Animal name: {{animal}}}</p>
    <p>Fur color: {{furColor}}</p>
    <p>Population: {{population}}</p>
    <p>Is extinct: {{isExtinct}}</p>
    <p>Is domesticated: {{isDomesticated}}</p>
  </div>
</template>

How would I do that? I know I can redirect via this.$router.push({ path });, but I've only used it for navigation, while here JSON response needs to be passed. Is this even a correct / good practice way of approaching this?

EDIT:

I tried this:

in GetAnimal.vue I added this data:

data: function() {
   return {
     animal:  {
       name: 'Cat',
       furColor: 'red',
       population: '10000',
       isExtinct: false,
       isDomesticated: true
}

and in DisplayAnimal.vue this:

<script>
    export default  {
        props:  {
            animal:  {
                name: {
                    type: String
                },
                furColor:  {
                    type: String
                },
                population: String,
                isExtinct: String,
                isDomesticated: String
            }
        }
    }

</script>

and in GetAnimal.vue I added this:

methods: {
            animals: function()  {
                alert("animals");
                this.$router.push({name: 'viewanimal',
                                query: {animal: JSON.stringify(this.animal)}});
            },

to try to display that test animal using the display component. However it just didn't work - I get an empty page.

like image 361
parsecer Avatar asked May 24 '20 16:05

parsecer


Video Answer


2 Answers

Using Vuex, you can solve this easily

Working example on netlify https://m-animalfarm.netlify.app/

code on github https://github.com/manojkmishra/animalfarm

enter image description here

GetAnimal.vue ( I have disabled axios call for testing and hardcoded info)

 <template>
 <form v-on:submit.prevent="getAnimal()">
   <textarea v-model = "animal" name = "animal" type="animal" id = "animal"
   placeholder="Enter your animal here">
  </textarea>
  <button class = "custom-button dark-button"
  type="submit">Get animal</button>
  </form>
 </template>
 <script>
 import axios from 'axios';
 export default 
 {
    name: 'App',
    data: function() {  return { info: '', animal: ''  }  },
    methods:  {
        getAnimal: function()  {
            // axios
            //   .get('http://localhost:8088/animalsapi?animal=' + this.animal)
             //   .then(response => (this.info = response.data),
                this.info={"fur-color": "yellow","population": 51000,"isExtinct":     
                            false,"isDomesticated": true },
                this.$store.dispatch('storeAnimals', this.info)
                //);
        }
    }
 }
 </script>

DisplayAnimal.vue

<template>
<div>
<p>Animal name: {{stateAnimal.animal}}</p>
<p>Fur color: {{stateAnimal.furColor}}</p>
<p>Population: {{stateAnimal.population}}</p>
<p>Is extinct: {{stateAnimal.isExtinct}}</p>
<p>Is domesticated: {{stateAnimal.isDomesticated}}</p>
 </div>
</template>
<script>
 import {mapState, mapGetters} from 'vuex';
export default {
computed:{  ...mapState({ stateAnimal:state => state.modulename.stateAnimal }),   
 },
}
</script>

modulename.js ( store module)

export default
{
 state: {stateAnimal:null,  },
 getters:{ },
 mutations: 
 {    ['STORE_ANIMALS'] (state, payload) 
    {  state.stateAnimal = payload;  
    console.log('state=',state)
   },

  },
 actions: 
 {  storeAnimals: ({commit}, data) => 
    { console.log('storeanim-data-',data);
      commit(  'STORE_ANIMALS', data   );  
    },     
  }
  }

Index.js (for vuex store), you can disable persistedstate as its for saving state if page is refreshed

import Vue from 'vue'
import Vuex from 'vuex'
import modulename from './modules/modulename'
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex)
export default new Vuex.Store({
plugins: [createPersistedState({ storage: sessionStorage })],
state: {  },
mutations: {  },
actions: {  },
modules: { modulename }
})

State is available/shared for all the components enter image description here

like image 125
Manoj Avatar answered Oct 07 '22 21:10

Manoj


Vue.component('product',{
  props:{
    message:{
      type:String,
      required:true,
      default:'Hi.'
    }
  },
  template:`<div>{{message}}</div>`,
  data(){...}
})

//html in the other component you axios call is in this component //<product meesage="hello"></product>
like image 26
Eli Sigal Avatar answered Oct 07 '22 20:10

Eli Sigal