Trouble arises when emitting events in Vue using eventHub

In the development of my component, there arises a need to emit an event at a specific point in its lifecycle. This emitted event is intended to be listened to by another sibling component.

To facilitate this communication, I am utilizing an event hub.

However, upon trying to execute eventHub.$emit('EventName'), I encounter an error denoted as Uncaught TypeError.

Beneath is the detailed error message logged in the console:

vue.js?3de6:2400 Uncaught TypeError: cbs[i].apply is not a function
at Vue$3.Vue.$emit (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:322:1), <anonymous>:2400:16)
at Vue$3.e.(anonymous function) [as $emit] (chrome-extension://nhdogjmejiglipccpnnnanhbledajbpd/build/backend.js:1:6235)
at VueComponent.importPlayers (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:178:1), <anonymous>:98:64)
at Proxy.boundFn (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:322:1), <anonymous>:130:14)
at Object.change [as fn] (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:261:1), <anonymous>:118:13)
at HTMLInputElement.eval (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:322:1), <anonymous>:2229:16)

The code snippet responsible for triggering the error is as follows:

importPlayers(e) {

    eventHub.$emit('AdminAddedPlayers');

    this.importing = true;
    this.success.import = false;
    ...
    ...
}

Although no other significant issues are apparent within the component, here is the involved component and the eventHub setup:

assets/js/components/Admin/AdminImportPlayersComponent

<template>
<div class="component">
    <!-- Some standard markup has been omitted for conciseness -->

    <template v-if="! importing && ! warning.invalid_data_submitted">
        <h4>Import Players</h4>
        <div class="form-group" :class="error.import ? 'has-error' : ''">
            <input type="file" @change="importPlayers($event)" id="file" class="form-control">
            <div v-if="error.import" class="help-block danger">
                You must select a valid excel file.
            </div>
        </div>
    </template>
</div>
</template>

<script>
import eventHub from '../../../events.js';
export default {
    data() {
        return {
            importing: false,
            error: {
                import: false,
                other: false,
            },
            warning: {
                invalid_data_submitted: false,
                invalid_fixed_data_submitted: false
            },
            success: {
                import: false
            },
            invalid_players: [],
            teams: [],
            loader_color: '#0d0394'
        }
    },
    methods: {
        importPlayers(e) {

            eventHub.$emit('AdminAddedPlayers');

            this.importing = true;
            this.success.import = false;

            var formData = new FormData();
            formData.append('players', e.target.files[0]);

            return this.$http.post('/admin/players/import', formData).then((response) => {
                if (response.data.invalid_player_data.length) {
                    this.invalid_players = response.data.invalid_player_data;
                    this.warning.invalid_data_submitted = true;
                    this.getTeams();
                } else {
                    this.success.import = true;
                }
                this.importing = false;
                this.error.import = false;
                this.error.other = false;
            }, (response) => {
                if (response.data.players) {
                    this.error.import = true;
                } else {
                    this.error.other = true;
                }
                this.importing = false;
                this.warning.invalid_data_submitted = false;
                this.success.import = false;
            });
        },
        submitFixedPlayers() {

            eventHub.$emit('AdminAddedPlayers');

            this.importing = true;

            return this.$http.post('/admin/players/import/fixed', {
                players: this.invalid_players
            }).then((response) => {
                // handle responses

            }, (response) => {
                this.importing = false;
            });
        },
        getTeams() {
            return this.$http.get('/admin/teams/fetch').then((response) => {
                // manage teams retrieval
            });
        },
        setDefaultTeams() {
            // set defaults for teams
        }
    }
}

assets/js/events.js

module.exports = new Vue()

This error in Vue springs from the following portion of Vue's source code:

Vue.prototype.$emit = function (event) {
    var vm = this;
    var cbs = vm._events[event];
    if (cbs) {
        cbs = cbs.length > 1 ? toArray(cbs) : cbs;
        var args = toArray(arguments, 1);
        for (var i = 0, l = cbs.length; i < l; i++) {
          cbs[i].apply(vm, args);
        }
      }
    return vm
  };

Answer №1

Solution

After experimenting with using the $on method to listen for events emitted by the eventHub, I discovered an important limitation: you cannot pass arguments directly within the $on method like this:

vm.$on('Event', this.callback(arg1));

This approach resulted in a TypeError.

According to the documentation, any arguments provided in the $emit method will automatically be passed onto the callback function in the $on method. For example:

vm.$emit('Event', args);

In practice, the correct way to handle this situation is demonstrated below:

vm.$emit('AdminAddedPlayers', 1)

vm.$on('AdminAddedPlayers', this.callback);

Upon execution, the callback function called by $on receives the argument like this:

this.callback(arg);

Here, the variable arg comes from the $emit method.

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

Upon receiving AJAX-content, the next iteration of the $.each function will be triggered

This question has been asked on an online forum in the past, but it was around four years ago and there may be a more efficient solution available now. In my code, I have a loop that sometimes requires additional data to be fetched through ajax calls. Af ...

Adding JSON to the data attribute within a set of DOM elements

I am in the process of developing a website dedicated to recipes, where I am using a Mustache.js template to load recipe information from a JSON file. The structure of my JSON file is as follows: { "recipes":[ {"name": "A", preparationTime: "40min", "serv ...

Building something in Vue that I previously created in React

I'm in the process of building my personal portfolio and I've set up a template in React to easily pull in my social media links using this code snippet. {this.state.contact.map((contact, index) => <a className="social-ic ...

Step up Vue.js with Phonegap without the need for any pre-existing templates or frameworks

Looking for guidance as a beginner in Vue.js and Phonegap. Seeking assistance to integrate Vue.js with Phonegap without relying on any templates or frameworks. A basic example of listing will suffice. Grateful for any help provided. Thank you! ...

Trouble with Sound during Quickblox Webrtc Audio Calls

I am having an issue with my audio calls. When I make a call to another user, everything seems fine except that I cannot hear any sound when speaking into the microphone. I am only interested in making audio calls. The call is initiated by pressing a butt ...

What could be causing wavesurferjs to exceed the boundaries of its parent div?

I need assistance with my wavesurferjs issue The waveform is overflowing the parent div This problem occurs for the first time and upon resize of the parent div Upon resizing, it should automatically adjust to fit the parent div Question: When the pare ...

I'm looking for a solution to correct the array output from my function in node

I have a function that is currently functioning, but I am in need of proper array sorting. First, I will display my code, followed by the current output and then the desired output. Can someone help me edit my entire code and output? var app = require(&a ...

The most convenient method for automatically updating Google Charts embedded on a webpage

I am facing an issue with refreshing a Google Graph that displays data from a MySQL database. The graph is being drawn within a webpage along with other metrics: Data Output from grab_twitter_stats.php: [15, 32], [14, 55], [13, 45], [12, 52], [11, 57], [ ...

Automatically updating quantity with the power of jQuery

I have created a spreadsheet where users can input their expenses and the total will update automatically. Initially, I have set some default numbers in my HTML which are editable for users to modify as needed. However, I am facing an issue with my JQuer ...

A simple way to deactivate a React component (or the onClick event itself) using the onClick event

I have come across similar inquiries, but unfortunately, none of the solutions provided seem to work in my particular scenario. I am hopeful that someone can shed some light on what might be causing the issue. In my ReactApp, there are 3 card components t ...

Grid of pictures resembling a masonry pattern

As I ponder this intricate dilemma, I am convinced that there must be a simple solution or alternative approach to finding the answer. My goal is to create a grid of random images without any gaps between them. I have an array of images that I want to dis ...

Is it possible to mimic a ref attribute with jest/rtl within a functional component?

I'm currently facing an issue with a functional component that includes a helper function. function Component() { imgRef = useRef(null) function helperFunction(node, ref) { if (!ref || !ref.current) return; ...do someth ...

JavaScript: Launching the current page in a new tab or window

Is it feasible to open a new window or tab from the existing HTML page? Absolutely, I am referring to the current HTML page itself. Not triggered by an external call like this: window.open('page.html', '_blank'); Possible through Jav ...

Unable to mark checkboxes in Bootstrap 4 Dropdown (triggered by vue.js) due to unresponsive behavior

When using Vue.js to open a Bootstrap Dropdown, I encountered an issue with selecting custom checkboxes within the dropdown menu. I have come across information about event.stopPropagation() potentially causing this problem, but I am unsure where to imple ...

Triggering a pop-up window to appear without user interaction on the specified date within the function

I am looking to automatically trigger a pop-up window when my website loads after a specific date that I define within a function. How can I set up the date function for this task? I want the pop-up window to appear automatically on 27/07/2011, and every ...

Having trouble with NextJS not updating state upon button click?

I am encountering a problem with my NextJS application. I am attempting to show a loading spinner on a button when it is used for user login. I have tried setting the `loading` state to true before calling the login function and then reverting it to fals ...

Array of materials for ThreeJS GLTFLoader

Attempting to load a model using GLTFLoader and apply different colors for each face of the object (cube) using a material array is not functioning as expected. var materials = [ new THREE.MeshPhongMaterial( {color: 0x552811,specular: 0x222222,shininess: ...

How can I adjust the gravity or positioning of a tipsy tooltip in jQuery?

Is there a way to adjust the position or gravity of Tipsy? The plugin offers various options for gravity that can be set through the script: nw | n | ne | w | e | sw | s | se Currently, I have set it to s position, as shown in this demo: http://jsfiddle. ...

Steps for removing a p5.js instance once three.js assets have finished loading

I am trying to implement a preload animation using a p5 sketch while loading a three.js gltf file onto my webpage. The idea is to have the p5 animation play while the heavy gltf file loads in the background. However, I am facing issues with triggering the ...

Ways to delete an element from an array in MongoDB

I am a beginner in the MEAN stack development. I am currently working on implementing this and this. I have been using the $pull method, but it seems that it is not working for me. I suspect that the issue might be due to the differences in my MongoDB stru ...