Using Vue to showcase the result of a form submission on a separate page

Working with a <form> in the context of vue has been successful as I am able to send the form data to the server, receive a JSON response, and print it on the console.

However, my current challenge involves displaying this JSON response on a different page. For example, I have two separate .vue files: GetAnimal.vue, responsible for fetching animal data from an API, and DisplayAnimal.vue, designed to showcase the retrieved animal's information. The task now is to pass the animal data received by 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: The JSON response consists of various attributes like:

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

The goal is to transfer this JSON data to DisplayAnimal.vue located at the /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>

Question arises: How can this be achieved? Although familiar with using this.$router.push({ path }); for navigation purposes, applying it to pass a JSON response is uncharted territory. Is this method considered correct or best practice?

EDIT:

An attempt was made by adding the following data to GetAnimal.vue:

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

Additionally, in DisplayAnimal.vue, the script block was updated to include:

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

</script>

Lastly, a method was introduced in GetAnimal.vue aiming to display the test animal using the display component. Unfortunately, the approach didn't yield results and resulted in a blank page.

Answer №1

Utilizing Vuex simplifies the solution to this issue

Live demonstration on netlify

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

GetAnimal.vue (Axios call disabled for testing; hardcoded data used)

 <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

Answer №2

To start off, consider creating a new folder named "services" and within it, add a file called service.js for your axios calls - this is not only good practice but also contributes to cleaner code organization. Next, implement Vuex for managing this type of data effectively.

Regarding the structure, assuming GetAnimal.vue serves as the parent component while DisplayAnimal.vue is the child component where you want to display the information. To test if this setup works, utilize props. Additionally, you can pass data from the child back to the parent using $emit(). It's highly recommended to incorporate Vuex for state management in this scenario.

Answer №3

Creating a Vue component named 'product' which takes a prop named 'message'. The message prop must be of type string, required and has a default value of 'Hi.' It renders the message within a div tag.
  
  // In another component where an axios call is made, this is how you can include the 'product' component: <product message="hello"></product>

Answer №4

To ensure a seamless user experience, I would pass the animal name/id as a route parameter to the display page. This way, the component responsible for fetching and displaying the relevant animal data can prevent users from encountering an incomplete page if they visit the display page directly through the URL.

If you need to share local state between pages, consider using Vuex as suggested by others.

EDIT:

As requested, here is some code added to my answer.

Routes:

const routes = [
  { path: "/", component: SearchAnimals },
  { path: "/viewanimal/:name", component: DisplayAnimal, name: "displayAnimal" }
];

DisplayAnimal.vue:

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

<script>
import axios from "axios";

export default {
  name: "DisplayAnimal",
  data: () => ({
    animal: {}
  }),
  methods: {
    fetchAnimal(name) {
      axios
        .get(`http://localhost:8088/animalsapi?animal=${name}`)
        .then(response => {
          this.animal = response.data;
        });
    }
  },
  created() {
    this.fetchAnimal(this.$route.params.name);
  }
};
</script>

SearchAnimals.vue:

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

<script>
export default {
  name: "SearchAnimal",
  data: () => ({
    animal: ""
  }),
  methods: {
    onSubmit() {
      this.$router.push({
        name: "displayAnimal",
        params: { name: this.animal }
      });
    }
  }
};
</script>

This example is basic, lacking error handling, but it offers a starting point for implementation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is the initial carousel element failing to set height to 100% upon loading?

If you take a look here, upon loading the page you will notice a DIV at the top. It is labeled "content" with "content_container" wrapped around it and finally, "page" around that. Clicking the bottom left or right arrows reveals other DIVs with similar ta ...

Nested Promise.all within another Promise.all appears to terminate prematurely, triggering a warning indicating failure to return from a promise

I am utilizing this function to be invoked within another Promise.all. However, I consistently encounter a warning message: Caution: a promise was generated in a handler but was not returned from it. Additionally, the function deleteFutureAppointments() ap ...

The $http.get() function in Angular fails to function properly when used in Phonegap DevApp

Trying to retrieve a JSON file in my Phonegap App using angulars $http is causing some issues for me. I have set up this service: cApp.factory('language', function ($http) { return { getLanguageData: function () { return ...

Issue with VueJS rendering data within a for loop

As a newcomer to VueJS, I appreciate your patience as I navigate through this. Let me provide as much detail as possible. I am currently working on a Vue app that needs to retrieve a response from a server, iterate through the data, and set a Vue data var ...

Having difficulty parsing JSON data using the MiniJson-Reader library

Recently, I encountered an issue while attempting to parse a JSON string in my C++ code using the library minijson. The snippet of code causing trouble is as follows: <<"version">> [&]() { result.setVersion(v.as_long()); } ...

Looking to implement a CSS effect that will hide content without removing the space it occupies on the page?

Is there a way to hide specific buttons within the right column of a 3-column table display? I am currently utilizing jQuery to achieve this function. The purpose behind hiding these buttons is to prevent any quick clicks that might interfere with the fa ...

Using Node.js to extract text from a local file on Azure using OCR technology

I recently started using the Azure OCR Service to extract text from images (https://learn.microsoft.com/de-de/azure/cognitive-services/Computer-vision/quickstarts/javascript#OCR). While things have been going smoothly so far with uploaded images, I am now ...

Using Ruby on Rails to merge multiple JSON responses from an API request

In my current project, I am facing a challenge where I need to make an API call to a client to retrieve product information by providing the product_id. Unfortunately, the client's API only allows one ID at a time, which complicates the task signific ...

Adding client-side scripts to a web page in a Node.js environment

Currently, I am embarking on a project involving ts, node, and express. My primary query is whether there exists a method to incorporate typescript files into HTML/ejs that can be executed on the client side (allowing access to document e.t.c., similar to ...

What is the best way to parse this JSON using Jackson?

My JSON data is structured like this: { "summary":{ "somefield1":"somevalue1", "Twilio":{ "field1":"value1", "field2":"value2" }, "Tropo":{ "field1":"value1", "field2":"va ...

Guide on implementing event listener for right click using pure JavaScript (VANILLA JS)

I need the div to appear wherever the cursor is holding down the right mouse button. In my scenario, I am using the following code: <div class="d-none" id="item"></div> #item{ position: absolute; top: 0; left: 0; w ...

Seeking help with executing JQuery Ajax functions within a foreach loop

Currently, I am engrossed in the study of programming and endeavoring to construct a website utilizing .Net Core. The predicament at hand pertains to my limited acquaintance with JavaScript while incorporating two JQuery/AJAX functions on my Index page - o ...

A step-by-step guide on including chess.js in your Create React App

I'm facing an issue while trying to incorporate the chess.js npm library into my Create React App. The error message "Chess is not a constructor" keeps popping up. Below is the code snippet I am using: import React from 'react'; import &apos ...

Generate a key pair using the cryto library and then use it with the json

There's a new method called generateKeyPair in node 10, and I am utilizing it in the following way: const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", { modulusLength: 4096, publicKeyEncoding: { type: "spki", format: "pem ...

Ugly consequences arise as Gulp stumbles upon uncharted territory during the uglify

I'm experiencing an issue with my squish-jquery task. Every time I run it, I encounter the following error: Starting 'squish-jquery'... events.js:85 throw er; // Unhandled 'error' event ^ Error at new JS_Par ...

Manipulating video volume using JavaScript injection

My web page includes a video, and I have successfully used JavaScript injection to control the play/pause functionality. Now, I am looking to also adjust the volume based on percentage. How can I create a function that decreases or increases the volume acc ...

Are you in the business of building JavaScript hubs?

I have a unique setup where my express server is in charge of handling all routing and session functionalities. I've envisioned a system where logged-in users can connect to distinct "hubs" based on the location of each hub. My idea was to treat each ...

connect the input to a factor using v-model

I currently have a value that I need the user to adjust. Here's my current setup: <input type="number" v-model="value" step="any"/> However, the internal value is in radians while I want the user to see and input a degree value. So, I want th ...

JavaScript Bug Report

Currently, I am immersed in a project that encompasses various languages like HTML, JS, and PHP. While working on one of the PHP functions, I stumbled upon an unexpected anomaly. To dissect it better, I decided to break it down into simpler functions: &l ...

Different ways to customize the v-select input icon

Is there a way to change the default material design icon in v-select from mdi-menu-down to mdi-chevron-down? Any suggestions on how I can achieve this? I found a solution to hide the default icon using ::v-deep. Here's an example: ::v-deep .custom-i ...