Updating Vue component property when Vuex store state changes: A step-by-step guide

As I work on developing a straightforward presentation tool using Vue js and Vuex to manage the app state, I am facing a challenge in implementing a feature that tracks changes in the presentation such as title modifications or slide additions/removals. Currently, my Vuex store structure is:

const state = {
    presentations: handover.presentations, //an array of objects retrieved from the DB
    currentPresentation: handover.presentations[0]
}

Within my Presentation component, the code looks like this:

export default {
    template: '#presentation',
    props: ['presentation'],
    data: () => {
        return {
            shadowPresentation: ''
        }
    },
    computed: {
        isSelected () {
            if (this.getSelectedPresentation !== null) {
                return this.presentation === this.getSelectedPresentation
            }
            return false
        },
        hasChanged () {
            if (this.shadowPresentation.title !== this.presentation.title) {
                return true
            }
            return false
        },
        ...mapGetters(['getSelectedPresentation'])
    },
    methods: mapActions({
        selectPresentation: 'selectPresentation'
    }),
    created () {
        const self = this
        self.shadowPresentation = {
            title: self.presentation.title,
            slides: []
        }

        self.presentation.slides.forEach(item => {
            self.shadowPresentation.slides.push(item)
        })
    }
}

Although I have managed to create a shadow copy of the presentation and detect changes effectively, I am struggling to update the shadow presentation when the actual presentation is saved. Since the savePresentation action is triggered in another component, I am unsure how to capture the 'save' event within the presentation component for updating the shadow presentation. If you have any insights on how I can achieve this functionality, your assistance would be greatly appreciated! Thank you in advance!

Answer №1

After exploring alternative solutions, I found a different approach to solve the problem I had initially asked about. Here is how I approached it:

Instead of having my vue store communicate an event to a component, as is typically done with vuex, I decided to revamp the structure of my presentation object. Originally, it looked like this:

{
    title: 'title',
    slides: []
}

I opted for a more intricate structure, which now looks like this:

{
    states: [{
        hash: md5(JSON.stringify(presentation)),
        content: presentation
    }],
    statesAhead: [],
    lastSaved: md5(JSON.stringify(presentation))
}

In the updated structure, the presentation object remains simple, but each presentation state now includes a hash generated from the stringified simple presentation object and the actual object itself. This allows me to generate a new state with a unique hash for every change in the presentation. By comparing the current state hash with the previously saved one tracked in the lastSaved property, I can easily implement undo/redo features by manipulating the states and statesAhead arrays. This solution surpassed my initial intentions and kept all my state management centralized within the vuex store without complicating or cluttering components.

I hope this explanation clarifies things for anyone who might find it useful. Cheers!

Answer №2

When I faced the challenge of updating properties in my user state, I came up with a solution that proved to be effective.

Updating User State in Vuex Store

updateUser (state, newProperties) {
    if (!state.user) {
        state.user = {}
    }
    for (var property in newProperties) {
        if (newProperties.hasOwnProperty(property)) {
            // Update the store state
            Vue.set(state.user, property, newProperties[property])
        }
    }
}

How to Use

Invoke the updateUser action from your Vue component

this.updateUser({status: 'active'})

Updated Object

{"user":{"emailVerified":true,"status":"active"},"version":"1.0.0"}

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

Error occurred while attempting to parse JSON on comment system

I've run into some issues with my comments system. Everything was working perfectly yesterday, but today I started getting errors. I'm using json to post comments without reloading the page, but now I'm encountering a "SyntaxError: JSON.pars ...

Efficiently Passing Data Between jQuery Dialog Boxes

English is not my strong suit, so please bear with me. I am currently working on a project using Jquery Dialog and I need to display multiple dialogs one after the other (dialog1 opens dialog2 which opens dialog3...) The issue I'm facing is that when ...

Managing multiple Socket.io connections upon page reload

I am currently developing a real-time application and utilizing Socket.io for its functionality. At the moment, my setup involves receiving user-posted messages through the socket server, saving this data to a MySQL database via the controller, and then b ...

Is there a way to show a loading icon during the image change process without using jQuery?

How can I add a loading icon to an image change event without using jQuery? I'm new to the coding world and Stack Overflow community, so please bear with me. I've been searching for a solution to my specific situation but haven't been able ...

Warning: The use of the outdated folder mapping "./" in the "exports" field for module resolution in the package located at node_modulespostcsspackage.json is deprecated

I recently upgraded my Node to version 16 and since then I have been encountering this issue while building my Angular app. Warning: The folder mapping "./" used in the "exports" field of the package located at ".../node_modules/postcss/package.json" is de ...

Is there a way to transform time into a percentage with the help of the moment

I am looking to convert a specific time range into a percentage, but I'm unsure if moment.js is capable of handling this task. For example: let start = 08:00:00 // until let end = 09:00:00 In theory, this equates to 100%, however, my frontend data ...

Tips on verifying the existence of a file in Nuxt

Currently working with Nuxt version 2.15.4 and I am looking to verify within my store code whether a file exists in the Nuxt directory using the fs-extra package. It's straightforward when dealing with modules because I can obtain the file path utili ...

What's the reason behind the refusal of my connection to localhost at port 3000 in Node.JS?

As a student venturing into the world of back-end development for the first time, I decided to dive into learning Node.JS. To kick things off, I downloaded a PDF book titled "Jumpstart Node.JS" from SitePoint. Following the provided instructions, I attempt ...

Managing the Response from an Ajax Call

Currently, I am in the process of developing a user registration form for my website and have implemented ajax to manage server-side processes. My main issue lies in effectively handling the response generated by my PHP code. The potential responses from t ...

Display a division in C# MVC 4 when a boolean value is true by using @Html.DropDownList

I have multiple divs stacked on top of each other, and I want another div to appear when a certain value is selected. I'm familiar with using JavaScript for this task, but how can I achieve it using Razor? Below is a snippet of my code: <div id=" ...

Can you explain the concept of injection context within Angular version 16 and later?

I have come across the term "Injection context" and am trying to understand what it entails. In Angular, there are several things that are connected to injection context: EnvironmentInjector#runInContext injectionContext runInInjectionContext inject() Fr ...

Is there a way to immobilize an object in JavaScript without resorting to Object.freeze()?

Is there a way to freeze the following object without relying on Object.freeze()? Let's find out: const obj = { a:'test', b:'Something' } ...

Can you explain the process of utilizing WebdriverIO (wdio) to determine the frequency of an element's occurrence?

Currently, I am working on creating an interaction test to validate my javascript code using WebdriverIO (wdio). The specific functionality I am looking to test involves deleting a node and verifying that the number of times a selector appears has decreas ...

Defining data types for an array of objects in a useState hook

I'm having trouble understanding the issue with my code. interface dataHistory { data: string, before: string | number, after: string | number, } I have an interface defined outside of the Functional Component and inside I specify its struct ...

Ways to update a component upon becoming visible in Angular

Within my Angular 4.3.0 project, the header, left panel, and right panels are initially hidden on the login page until a successful login occurs. However, once they become visible, the data is not pre-loaded properly causing errors due to the ngOnInit meth ...

Expanding the functionality of the Ember JSONAPIAdapter for retrieving JSON data from a specified URL

As a newcomer to Ember.js, I am currently delving into understanding how Ember works. One issue I have encountered is calling my Django API from an Ember.js route using the following code: this.store.findAll('MYMODEL', 'ANOTHER_MODEL_ID&apos ...

What is the best way to eliminate all occurrences of a specific element within an array?

I'm currently facing an issue with my code - it's supposed to remove all instances of a certain item from an array, but it's not working as expected. Can anyone help me identify what I'm doing wrong? let nums = [1, 90, 90, 1123, 90, ...

provide a hyperlink to the icon located in front of the navigation bar

I'm struggling to come up with a suitable title for this issue. What I am trying to achieve is placing a small icon in front of the navbar so that visitors can click on it and be directed to another site. Initially, I attempted to place the icon using ...

Converting Strings into Variable Names in Vue.js: A Step-by-Step Guide

Hi everyone, I was wondering if there's a way to convert a string into a variable name. For example, I want to convert "minXLabel" to minXLabel so that I can use it within span tags like this: <span>{{minXLabel}</span>. I current ...

Converting JSON data retrieved from a URL into HTML format

I have a JSON output from a URL that I need to format into html. The structure of the JSON data is as follows: prtg-version "xxxxxxx" treesize 0 channels 0 name "Downtime" name_raw "Downtime" lastvalue "" lastvalue_raw "" 1 name ...