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

https://i.sstatic.net/gzZAI.png

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 https://i.sstatic.net/ikF4t.png

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

Issue occurs when using Angular Firebase $createUser method

I'm stuck on this issue. I'm attempting to set up a user with AngularFire using $firebaseAuth instead of the deprecated FirebaseSimpleLogin, as advised in the documentation. I am confident that the form is submitting a valid email and password, b ...

In ReactJS, the process of rendering a functional component differs from that of a class component

I have a class component that looks like this: import { Component } from 'react'; import { DEFAULT_HPP, DEFAULT_PAGE, DEFAULT_QUERY, PARAM_HPP, PARAM_PAGE, PARAM_SEARCH, PATH_BASE, PATH_SEARCH, } from '../../constants'; ...

Model for handling Node/Express requests

I always saw Node.js/Express.js route handlers as akin to client-side EventListeners such as onClick, onHover, and so on. For example: document .getElementById('btn') .addEventListener('click', function() { setTimeout(functi ...

Create a video player in your HTML code using the class "afterglow", and also link a separate class to it for additional styling

I'm encountering some challenges with a project that involves a JS file for a Bootstrap modal popup and an HTML5 video player. The issue I'm facing is that I am unable to link the class for the video player theme. Can anyone here assist me in ide ...

Set tab navigation widget with a fixed height

I am struggling with setting a fixed height for my tabs widget so that when I add more content, it will display a scrollbar instead of expanding endlessly. I have checked the CSS and JS files but cannot figure it out. It is important for me to contain this ...

Is utilizing v-model to update the Vuex store a recommended practice?

Hello there! As a newcomer to Vue, I find myself facing a dilemma that has been weighing on my mind. I'm confused about whether we should utilize the v-model directive to make changes to the Vuex store. While Vuex guidelines suggest modifying the stor ...

Capturing user inputs in PHP or AJAX

Is there a way to capture keystrokes on a web page regardless of where the user is focused? For example, if someone has the webpage open and they press '1', can it trigger an action? And if they press '2', can something else happen wit ...

implementing select2 and binding an event to it

I have a simple select2 setup where I am passing a common class in the options and trying to trigger a jQuery event on every change or click of an item in the dropdown. Here is my code snippet: <select name="transferfrom" id="transferfrom" data-placeho ...

Using JQuery to target the input value based on its ID

When trying to extract the value of the input with id "registration_type," I entered the following command in the console: $('#registration_type') The output displayed was: <input id=​"registration_type" name=​"contact_registration[ty ...

When working with create-react-app and TypeScript, you may encounter an error stating: "JSX expressions in 'file_name.tsx' must

After setting up a React project with TypeScript using the CLI command create-react-app client --typescript, I encountered a compilation error when running npm start: ./src/App.js Line 26:13: 'React' must be in scope when using JSX react/r ...

Using Vuejs 2 to switch the .active class on and off

Check out this HTML code: <nav class="nav nav-pills"> <li v-bind:class="{ 'active': isActive }" class="text-center"> <img class="img-responsive" src="{{ FuImg::asset(&apo ...

Can JavaScript be used to update/override Prototype version 1.4 to version 1.7 on a different website?

(I'm uncertain about the best way to phrase this question, feel free to make changes). I am in the process of embedding a JS widget onto a different website that is using Prototype.js Version 1.4. I have incorporated jQuery into my widget and have it ...

Importing PNG files through AJAX and rendering them on a canvas using a Flask server

How can I render a PNG image received via an AJAX call in a canvas? A video file (mp4) is uploaded via AJAX to a Flask server. The first frame is extracted using Cv2, saved, and then returned to the client. I am able to retrieve the PNG data as a string, ...

Sending data from PHP to JavaScript using AJAX

I'm encountering an issue trying to pass data from a PHP file to a JavaScript file using echo. My PHP file contains the following code snippet: <?php ...establishing connection and retrieving list from database... for($i=0;$i<sizeOf($li ...

Having issues installing Parcel through npm - Encountered an error while parsing package.json information

After creating a package.json file using the command npm init in my project folder, I proceeded to run npm i parcel --save-dev which resulted in an error message: C:\Users\XPRESS\Desktop\starter>npm i parcel --save-dev npm ERR! code ...

Having difficulty grasping the significance of the data received from the API response

Currently, as I am working on my personal Portfolio for a Web Developer course, I have encountered an issue with correctly implementing my API to retrieve information from the database. Previously, I faced no problem when using a .json file, but now, I am ...

Looking for ways to detect memory leaks in your JavaScript application using Selenium?

While utilizing Java and Selenium for automated testing of a JavaScript web application, the issue of memory leaks has arisen. I am interested in ways to effectively test for them. Is there a simple method to obtain memory usage and other profiling data fo ...

In my Vue project, I am required to extract only the numerical value from a select option text and disregard the rest of the text

Currently, I am in the process of learning Vue and have taken on the task of creating a basic tax calculator. The challenge is to display the result in real-time without requiring a "show total value" button. Everything seems to be functioning well except ...

Retrieve the list of device tokens for the APNS service

Is it possible to retrieve a list of all device tokens on which my app is installed through an APNS endpoint? I am aware of the feedback service that provides the status of devices to whom messages are sent, but I believe this is only after the message ...

What is the best way to save the city name received from geolocation into a variable and then make an AJAX request?

<script> new Vue({ el: '#fad' , data: { data: {}, }, mounted() { var self = this; navigator.geolocation.getCurrentPosition(success, error); function success(position) { var GEOCO ...