Utilize eventbus in Vue.js to transmit the data of the element that has been clicked

As a newcomer to Vue.js, I appreciate your patience. In my Vue project, I am focusing on displaying Patients and their data without utilizing Vuex.

The project consists of 3 layers:

1. Home.vue file where the patient data is imported.

2. Patients.vue component which contains a for loop to display all patients using props to access the patient Array.

3. ViewPatient.vue view where I aim to show more details of the selected Patient by inheriting the name and making an additional call to the endpoint for observations related to that specific patient.

I have experimented with different methods such as eventbus, dynamic router, and data-attributes.

Home.vue

<template>
  <div class="container">
    <keep-alive>
      <Patients :PatientsData="PatientsData" />
    </keep-alive>
  </div>
</template>

<script>
// @ represents /src
import PatientsData from "../data/messages";
import Patients from "../components/Patients.vue";

export default {
  name: "home",
  data() {
    return {
      PatientsData: PatientsData
    };
  },

  components: {
    Patients
  }
};
</script>

Patients.vue (component)

<template>
  <div v-if="PatientsData.length > 0">
    <div class="row row-eq-height">
      <div v-for="PatientData in PatientsData" class="col-12 col-sm-6 col-md-3 mb-3" :key="PatientData.content" :data-id="PatientData.content" @click.prevent="passPatientData" >
        <router-link to="/patient" >
          <div class="col-12 patientsTiles p-4">
            <p class="patientsName">
              <span>Name:</span>
              {{ PatientData.content }}
            </p>
            <p class="patientsCPR">
              <span>CPR Number:</span>
              {{ PatientData.subject }}
            </p>
            <p class="patientsAge">
              <span>Age:</span>
              {{PatientData.age}}
            </p>
            <i :class="['fa', 'fa-star', {important: PatientData.isImportant}]"></i>
          </div>
        </router-link>
      </div>
    </div>
  </div>
</template>

<script>
import router from "../main";
import { eventBus } from "../main";
export default {
  props: {
    PatientsData: Array,
  },
  data(){
    return{
      patientName: ""
    }
  },


  methods: {
    passPatientData() {
      this.patientName = this.PatientData;
      alert(this.patientName);

      eventBus.$emit("passPatientData", this.patientName);
    }
  }

};
</script>

ViewPatient.vue (view)

<template>
  <div class="container">
    <h1>The Patient Detail</h1>
  </div>
</template>

<script>
// @ represents /src
import { eventBus } from "../main";

export default {
  props: {
    // patientId:{
    //     type: String
    // } 
  },
  data() {
    return {
      selectedPatient : ""
    };
  },

  created() {  
      eventBus.$on("passPatientData", data  => {  
        this.selectedPatient = data;
 })}
}
</script>

It seems the issue lies within the passPatientData function. The this.PatientData is empty, and I'm struggling to pass the clicked element's data to the empty string (this.patientName) so that it can be emitted to the eventbus.

passPatientData() {
      this.patientName = this.PatientData;
      alert(this.patientName);

      eventBus.$emit("passPatientData", this.patientName);
    }

Answer №1

Here is the method I used that successfully resolved my issue with just a few adjustments:

Shoutout to @bbsimonbb for providing an answer, but I found another approach more suitable for my simple task.

Within Patients.vue, while iterating through patients, I made a tweak to the click event: I am now passing the individual element being clicked, saving me a significant amount of time.

<div v-for="PatientData in storedPatients" class="col-12 col-sm-6 col-md-3 mb-3" :data-id="PatientData.content" @click="passPatientData(PatientData)" >

Previously:

@click="passPatientData"

Updated to:

@click="passPatientData(PatientData)"

Then, within my event bus, I can effectively handle the data being passed:

methods: {
    passPatientData(element) {
      this.patientName = element.content;
      alert(this.patientName);

      eventBus.$emit("passPatientData", this.patientName);
    }
  }

The goal is to send the patientName to ViewPatient.vue file via eventbus and trigger a new API endpoint like this: endpoint/patient/(patientName). The response from this endpoint will contain detailed information about the specific patient clicked in patients.vue

This solution has proven successful. Hopefully, it proves helpful to others facing similar challenges.

Answer №2

If you've chosen to forgo Vuex, it doesn't mean you should skip using a store altogether. A basic store can be as simple as an object within the root Vue's data, passed around via provide and inject functions. This allows you to store shared data efficiently.

Using this approach is much easier to understand than relying on an event bus. By accessing the shared state directly from Vue components through an object dedicated solely to storing state, you have more control over how your data is managed.

// Home.vue
export default {
    name: "home",
    provide: { mySharedData: this.mySharedData },
    data() {
        return {
            mySharedData: {
                patientData: {}
            }
        };
    },
    created() {
        fetch("http://patientData")
            .then(response.json)
            .then((patientData) => this.mySharedData.patientData = patientData)
    }
    ...

// Then, in all other components of your app...
export default {
        inject: ['mysharedData'],
        ...
    }

This method leverages Vue reactivity to automatically propagate changes throughout your application. It's important to grasp how Vue handles reactive properties - ensure that all necessary props are initialized beforehand rather than adding new ones later. If dynamic updates are required, consider utilizing Vue.set().

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

Showcasing the outcomes of an array on a separate webpage

I'm currently tackling a scenario where I need to load an array from one page and display the results on another using javascript/jQuery. The process involves a user selecting an option from a dropdown menu, which triggers the display of the correspon ...

Propagation of errors in promises between classes in a Node environment

I am currently in the process of refactoring my code to be more object oriented and encountering difficulties with handling promise errors between instances of classes. In my Page.js file: exports.Page = class { constructor(link, limiter){ this.lin ...

The Reason Behind Component Non-ReRendering in Redux

I am currently facing an issue with my component and reducer. The `componentDidMount()` method in my component is calling a server to get some data, but the component doesn't re-render after the action is performed. I have checked my code multiple tim ...

Loading custom places in ArcGIS from a file or database

Hey there, I was wondering about loading custom places with Arcgis similar to Google maps loading from a .xml file. I noticed that Arcgis uses examples saved in .json format, but when I tried putting the example .json on my local server it wouldn't lo ...

Tips on resolving the error message "Property ... is not present on type 'IntrinsicAttributes & ...' in NextJS"

In my nextjs application, I have a Navbar component that accepts menu items as props: <Navbar navitems={navigationItems} /> The navigationItems prop is an array of objects. Within the Navbar component, I have defined the following: export interface ...

What is the best way to erase the contents of a pop-up window?

Whenever I click on an event in the calendar, a popup window appears displaying textboxes and a list of items. The issue arises when I close the popup after selecting an event with items in the list; the same items show up for other events without refreshi ...

Best method to generate an element using any jQuery selector string

What I want to accomplish I am looking to create an element that matches any given selector string. Here's a quick example: var targetString = "a.exaggerated#selector[data-myattr='data-here']"; var targetEl = $(targetString); if(!targetE ...

Encountering an issue while trying to generate a React app with the command npx create-react-app

Recently venturing into the world of React, I have successfully created several apps. However, my latest attempt to create a new app has hit a snag. Currently running Node version v15.6.0 and npm 7.4.0 on Windows 10. The file tree I'm currently worki ...

The $http request is aborted

I'm having trouble with sending a post request to the server from my login form as it keeps getting canceled. Below is the controller code: angular.module('app.signin', []) .controller('SigninController', ['$http', func ...

Determine which link the user has clicked on using JavaScript

One of the challenges I'm facing is determining which link users are clicking on a specific page and sending that information to the server via AJAX. Although I have the AJAX functionality in place, I am struggling with capturing the link click data. ...

What is the best way to implement backup style attributes for a React JS component?

Is there a method to implement fallback style properties for a component? For example: var inlineStyle = { display: '-webkit-box', display: '-webkit-flex', display: '-moz-box', display: '-moz-flex', ...

"click on the delete button and then hit the addButton

I have created a website where users can save and delete work hours. I am facing an issue where I can save the hours at the beginning, but once I delete them, I cannot save anything anymore. Additionally, when I reload the page, the deleted data reappears. ...

Display the message "currently being loaded" on a Django platform

I'm a newcomer to django and styling and I have two things I want to address. First, I have an algorithm running on the upload file that takes time to load. I want to display a loading message until the output.csv file is generated and ready for downl ...

Triggering an excessive number of events upon attaching a listener to my sprites

I'm experimenting with creating a simple Cocos2d-js demo featuring clickable balls that can be moved. Here is how I am generating the balls: var listener = cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY_ONE, ...

Error Message: A key is being provided to the classes property that is not implemented in the current context

Trying to customize Material-UI styles with makeStyles() as outlined in the documentation but encountering a warning when passing a classname in the parent component that is not specified in useStyles. The warning message reads: Warning: Material-UI: th ...

What is the best way to use jQuery to select a group of table rows based on the value of a

My current issue involves using a jQuery selector to move table rows "UP" and "Down." Here is the Table structure in HTML: jQuery Portion : $(".up,.down").click(function() { var row = $(this).parents("tr:first"); if ($(this).is(".up")) { ...

Transforming a datetime-local Element into a Date Object

I am currently utilizing the HTML5 element datetime-local with the requirement of having two different formats for the date. One format will be stored as a date object in the database, while the other format will be used as a string to set the datetime-loc ...

Navigate to the AngularJS documentation and locate the section on monitoring data changes after a dropdown selection

Just starting out with AngularJS and Stack Overflow, so I hope I am asking this question correctly. I am working on a single-page application with editable text inputs. Two select drop-downs are used to control which data is displayed - one for time perio ...

Tips for incorporating animation while altering element styles within JavaScript

I am looking to incorporate a sliding animation that moves the element downward when the display property is set to block, and upward when it's set to none or an empty string, here is the current JavaScript code I have: <script> function showQ ...

Ember.js encountering an "Access-Control-Allow-Origin" error with Ajax

Seeking opinions on how to resolve the Access-Control-Allow-Origin issue in this simple Ajax code snippet. Attempts to define the Ember "Access-Control-Allow-Origin": "* " have been unsuccessful. Has anyone with a similar problem found a solution? The URL ...