1

I have a local database that will be updated with pusher. This database is stored in JSON and the component will load and filter out what is not needed, making it impossible to add a watcher to the raw data.

My idea (please advice me if there are better solution) was to add a listener for a custom event, then trigger this event when the DB is updated. The only event I'm able to trigger is 'CLICK', with a simple $('.vue-template').trigger('click');

This is paired with a simple @click="doSomething" on the element I chose as my target.

This is not ideal because I don't want to fetch the data on any click, but only when the DB is updated, so I've tried @customevent="doSomething" but it doesn't work

Any help?

EDIT: More code

<template>
    <div class="listen listen-database-teachers"
         @dbupdate="testAlert">
        <span v-for="teacher in teachers"
              class="pointer btn btn-sm btn-default destroy-link"
              :data-href="computedHref(teacher)"
              :data-person="personIdentifier(teacher.person)"
              :data-personid="teacher.person_id">
        {{ personIdentifier(teacher.person) }} <span class="glyphicon glyphicon-remove"></span>
        </span>
    </div>
</template>

<script>
    export default {
        props: ['circleId'],
        data () {
            return {
                loading: false,
                teachers: null,
                error: null
            }
        },
        created () {
            // fetch the data when the view is created and the data is
            // already being observed
            this.fetchData();
        },
        methods: {
            fetchData() {
                this.error = this.teachers = this.categories = null;
                this.loading = true;

                var teachers = $(window).localDatabase('teachers', $(window).planner('currentSchoolId'));

                var searchCircle = this.circleId,
                    filtered_teachers = [];
                $.each(teachers, function(index, teacher){
                    if(teacher.membership_id == searchCircle)
                        filtered_teachers.push(teacher);
                });
                this.teachers = filtered_teachers.sort(function(a, b) {
                    return personIdentifier(a.person) > personIdentifier(b.person);
                });

                this.loading = false;
            },
            computedClass(teacher){
                return 'pointer btn btn-sm btn-default draggable membership-draggable-'+teacher.membership_id+' destroy-link'
            },
            computedHref(teacher){
                return window.links.destroy_membership
                        + '?association-id='+teacher.id
                        + '&circle-id='+teacher.circle_id;
            },
            testAlert: function(){
                return alert('success');
            }
        }
    }
</script>

EDIT 2: attempt to use BUS

Remember that I use Laravel Mix.

app.js

window.vue_bus = new Vue();

master.js

function handleDatabaseUpdate(){
    window.vue_bus.$emit('refresh-data');
}

component

created () {
        // fetch the data when the view is created and the data is
        // already being observed
        this.fetchData();
        window.vue_bus.$on('refresh-data', this.testAlert());
    },

I've isolated the relevant bits of the code. This executes testAlert() when the component is mounted, but it returns an error cbs[i] undefined when I call handleDatabaseUpdate() from browser console (on Firefox).

11
  • On Vue you can raise your custom events you can also write your component Commented Jun 16, 2017 at 9:56
  • @Max that's what I thought too, but how are they triggered? My understanding is that the only way is to click on the items Commented Jun 16, 2017 at 10:01
  • ... methods: { raiseMyEvent() { this.$event("myEvent", myData); } } replace $('.vue-template').trigger('click'); with raiseMyEvent() Commented Jun 16, 2017 at 10:04
  • user vm.$emit to trigger an event on the current instance Commented Jun 16, 2017 at 10:05
  • @Max can this work from outside the component? I need to call this when the DB is updated outside the vue app Commented Jun 16, 2017 at 10:13

1 Answer 1

1

This is a case where I might use an event bus.

A bus is created by simply creating an empty Vue.

const bus = new Vue()

In whatever function you have outside that is dealing with the database, you can emit an event using the bus.

function handleDatabaseUpdate(){
   //do database things
   bus.$emit("refresh-data")
}

Then in your component, add a handler.

created(){
    bus.$on("refresh-data", this.fetchData)
}

Since it looks like you are using single file components, you will have to make the bus available to both the component and your database manager. You can do that two ways. Quick and dirty, expose the bus on the window.

window.bus = new Vue()

Second, you can create the bus in its own module and import the module into all the places you need to use it.

bus.js

import Vue from "vue"

const bus = new Vue()
export default bus;

And in the code that deals with the database and in your component, import the bus.

import bus from "/path/to/bus.js

That said, the reason you cannot listen to jQuery events in Vue is that jQuery uses it's own event system and Vue's listeners will never catch jQuery events. If you still wanted to use jQuery, you could emit a custom event in jQuery and listen to that custom event also using jQuery. You would just have to dispatch the event to fetchData.

created(){
    $("thing you sent the event from").on("refresh-data", this.fetchData)
}

Finally, this is also a case where a state management system (like Veux) would shine. State management systems are intended for cases like this where state could be changing in many places and automatically reflecting those changes in the view. There is, of course, more work implementing them.

Sign up to request clarification or add additional context in comments.

6 Comments

I keep getting TypeError: cbs[i] is undefined when calling handleDatabaseUpdate() from console. I used the window.bus approach because the other way was saying bus was undefined... what am I doing wrong?
@clod986 What is the code for handleDatabaseUpdate? I assume you have a variable in there called cbs, possibly an array, but it has no values.
I have no idea where that comes from, I pasted your code in order to have it work before changing it... but it doesn't do much. I realized that the function (I'm still using the alert for quicker debugging) gets called every time the component is created, while it shouldn't
@clod986 I need to see code in order to help. The handleDatabaseUpdate function I wrote was just a placeholder for whatever you have that gets the database data.
I've updated my question with another edit to show you the relevant bits of the code. Thanks for the time
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.