3

I have a page where an object with nested array values are passed in from the parent component. The user can then, using a series of events and components manage the data in these subscriptions. Currently I'm facing an issue where when a subscriptionId is removed from the props, conditions on the page aren't changing, but they do when it's added.

Child Component

export default {
    props: {
        // Format of this object is:
        // { "gameId": [
        //     'subscriptionId',
        //     'subscriptionId',
        // ] }
        subscriptions: {
            type: Object,
            required: true
        }
    },
    watch: {
        subscriptions: {
            handler: function (newSubscriptions, oldSubscriptions) {
                // NEVER gets fired when `subscriptionId` deleted from array list, but is fired when a new subscription is added
                console.log('handler');
                }
            },
            deep: true
        }
    },

I suspect this might be related to how I'm removing the array from the object. Essentially I'm copying the array, deleting the index in question and overwriting the original array. My hope with this approach is that the watcher wouldn't be needed but it appears to have no impact. Here's the code that exists on the parent component to update the subscriptions:

Parent Component

// Works great, don't have any issues here
handleSubscribed (subscriptionId) {
    let newSubscriptions = [subscriptionId];

    if (this.subscriptions.hasOwnProperty(this.currentGame.id)) {
        newSubscriptions = this.subscriptions[this.currentGame.id];
        newSubscriptions.push(subscriptionId);
    }

    this.$set(this.subscriptions, this.currentGame.id, newSubscriptions);
},
handleUnsubscribed (subscriptionId) {
    // if there's more than one, delete only the one we're looking for
    if (this.subscriptions.hasOwnProperty(this.currentGame.id) && this.subscriptions[this.currentGame.id].length > 1) {
        let newSubscriptions = this.subscriptions[this.currentGame.id];

        delete newSubscriptions[newChannels.indexOf(subscriptionId)];

        this.$set(this.subscriptions, this.currentGame.id, newSubscriptions);

        // shows my subscription has been removed, but GUI doesn't reflect the change
        console.log('remove-game', newSubscriptions); 
        return;
    }

    this.$delete(this.subscriptions, this.currentGame.id);
},

I was hoping watch might be the solution, but it's not. I've looked over the reactive docs several times and don't see a reason for why this wouldn't work.

VueJS version: 2.5.7

6
  • can you make any fiddle of this ? Commented Jul 2, 2018 at 3:10
  • 1
    Have you tried using Vue.delete inside the if block instead of delete? Commented Jul 2, 2018 at 6:09
  • or splice Commented Jul 2, 2018 at 9:16
  • @DigitalDrifter I'm shocked, but that seems to have solved it. This is some extensive stuff it seems to make it work that deep under the covers... Commented Jul 2, 2018 at 21:46
  • Cool, glad that did the trick. I assume the cause is that using the js delete keyword destroys the observable and hence the object is no longer reactive as expected. Vue's set and delete methods ensure they remain so. Commented Jul 2, 2018 at 22:22

1 Answer 1

0

Use Vue.delete instead of the delete keyword.

The object is no longer observable when using delete, therefore not reactive.

Delete a property on an object. If the object is reactive, ensure the deletion triggers view updates. This is primarily used to get around the limitation that Vue cannot detect property deletions, but you should rarely need to use it.

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

Comments

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.