Establishing Accessor and Mutator Methods

The variables startStopA... and InitialValueA... that were originally in the component TableFields.vue need to be relocated to the store file index.js. However, upon moving them to the store, an error appears stating that setters are not set. I have extensively consulted the documentation and attempted various solutions, but I have been unsuccessful in resolving the issue.

Component TableFields.vue

<template>
  <div>
    <div class="wrapper" v-for="(field, index) in fields" :key="index">
      <table>
        <tr>
          <th>{{ field }}</th>
          <td class="sign">{{ randomSign[index] }}</td>
          <td class="value">{{ initialValues[index].toFixed(2) }}</td>
          <td v-show="$store.state.randomSign[index] === '+'">&#x2B06;</td>
          <td v-show="$store.state.randomSign[index] === '-'">&#x2B07;</td>
        </tr>
      </table>

      <button
        @click="toggleInterval(field)"
        v-if="field === 'A'"
        :class="[startStopA ? 'button-start' : 'button-stop']"
      >
        <span v-show="startStopA">Stop</span>
        <span v-show="!startStopA">Start</span>
      </button>

      <button
        @click="toggleInterval(field)"
        v-if="field === 'B'"
        :class="[startStopB ? 'button-start' : 'button-stop']"
      >
        <span v-show="startStopB">Stop</span>
        <span v-show="!startStopB">Start</span>
      </button>

      <button
        @click="toggleInterval(field)"
        v-if="field === 'C'"
        :class="[startStopC ? 'button-start' : 'button-stop']"
      >
        <span v-show="startStopC">Stop</span>
        <span v-show="!startStopC">Start</span>
      </button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'TableFields',
  data () {
    return {
      startStopA: true,
      startStopB: true,
      startStopC: true,
      initialValueA: 3,
      initialValueB: 3,
      initialValueC: 3,
      arraysInterval: null
    };
  },
  computed: {
    ...mapState([
      'changes',
      'timer',
      'fields',
      'signs',
      'randomSign',
      'randomNumbers'
    ]),

    initialValues () {
      let array;
      array = [
        this.initialValueA,
        this.initialValueB,
        this.initialValueC
      ];
      return array;
    }
  },
  methods: {
    ...mapMutations(['replaceNumbersArray']),

    toggleInterval (field) {
      // button toggle
      if (field === 'A') {
        this.startStopA = !this.startStopA;
        if (this.startStopA) {
          this.timer[0] = setInterval(() => {
            this.calculations('A');
          }, 2000);
        } else {
          clearInterval(this.timer[0]);
        }
      }
      if (field === 'B') {
        this.startStopB = !this.startStopB;
        if (this.startStopB) {
          this.timer[1] = setInterval(() => {
            this.calculations('B');
          }, 2000);
        } else {
          clearInterval(this.timer[1]);
        }
      }
      if (field === 'C') {
        this.startStopC = !this.startStopC;
        if (this.startStopC) {
          this.timer[2] = setInterval(() => {
            this.calculations('C');
          }, 2000);
        } else {
          clearInterval(this.timer[2]);
        }
      }
      if (!this.startStopA && !this.startStopB && !this.startStopC) {
        clearInterval(this.arraysInterval);
      }
    },
    calculations (field) {
      this.fields.forEach((value, index) => {
        if (field === value) {
          this.randomSign[index] = this.signs[
            Math.floor(Math.random() * this.signs.length)
          ];
          const date = new Date();
          const newChange = [];

          newChange.field = field;
          newChange.indicator = this.randomSign[index];
          newChange.value = this.randomNumbers[index];
          newChange.time = date.toLocaleTimeString();

          this.changes[index].push(newChange);
        }
      });

      if (field === 'A') {
        this.randomSign[0] === '+'
          ? (this.initialValueA += this.randomNumbers[0])
          : (this.initialValueA -= this.randomNumbers[0]);
      }

      if (field === 'B') {
        this.randomSign[1] === '+'
          ? (this.initialValueB += this.randomNumbers[1])
          : (this.initialValueB -= this.randomNumbers[1]);
      }

      if (field === 'C') {
        this.randomSign[2] === '+'
          ? (this.initialValueC += this.randomNumbers[2])
          : (this.initialValueC -= this.randomNumbers[2]);
      }
    }
  },
  beforeUpdate () {
    const array = [this.startStopA, this.startStopB, this.startStopC];
    array.forEach((value, index) => {
      if (!value) {
        clearInterval(this.timer[index]);
      }
    });
  },
  mounted () {
    console.log(`${this.changes}`);
    this.arraysInterval = setInterval(this.replaceNumbersArray, 2000);

    this.fields.forEach((value, index) => {
      this.timer[index] = setInterval(() => {
        this.calculations(value);
      }, 2000);
    });

    this.initialValueA = this.$root.initialValueA || 3;
    this.initialValueB = this.$root.initialValueB || 3;
    this.initialValueC = this.$root.initialValueC || 3;

    this.startStopA = !this.$root.startStopA || !this.startStopA;
    this.startStopB = !this.$root.startStopB || !this.startStopB;
    this.startStopC = !this.$root.startStopC || !this.startStopC;

  },
  beforeDestroy () {
    clearInterval(this.arraysInterval);

    this.$root.initialValueA = this.initialValueA;
    this.$root.initialValueB = this.initialValueB;
    this.$root.initialValueC = this.initialValueC;

    this.$root.startStopA = !this.startStopA;
    this.$root.startStopB = !this.startStopB;
    this.$root.startStopC = !this.startStopC;

    this.timer.forEach(value => {
      clearInterval(value);
    });
  }
};
</script>

File store/index.js:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    changes: [],
    timer: [0, 0, 0],
    fields: ['A', 'B', 'C'],
    signs: ['+', '-'],
    randomSign: ['+', '+', '+'],
    randomNumbers: []
  },
  mutations: {
    replaceNumbersArray (state) {
      // Replaces random A, B, C... numbers at specified time intervals
      const A = Number((Math.random() + 1).toFixed(2)); // first number A
      const B = Number((Math.random() + 1).toFixed(2)); // first number B
      const C = Number((Math.random() + 1).toFixed(2)); // first number C
      state.randomNumbers.splice(0, 3, A, B, C);
      console.log(state.randomNumbers);
    }
  }
});

export default store;

GitHub repository:
https://github.com/SrdjanMilic/Super-Dynamic-Data

Codesandbox link:
https://codesandbox.io/s/super-dynamic-data-djpxe

Answer №1

If you wish to change a computed property in Vuejs, it is essential to create a setter for each property that needs mutation because computed properties are typically read-only:

According to the VueJS documentation:

Computed properties are usually for getting values only, but setters can be provided when necessary

The example of a computed property with both getter and setter functions would look something like this (as shown in the VueJS docs):

fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }

In order to make mutations reusable within your codebase, I suggest implementing them as store actions or mutations and then triggering them from your component methods (or using mapActions...etc).

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

A Node.js function may not provide a response immediately due to a pending request

Here is a simple upload method using node.js and express.js: upload: function(req, res, next){ // Loop through each uploaded file async.each(req.files.upload, function(file, cb) { async.auto({ // Create new path and unique file ...

What is the best way to navigate through a webpage to find a specific folder and show its contents on the page?

My goal is to design a webpage where users can browse their computer for a specific folder, select it, and have its content displayed on the webpage. I am fairly new to creating pages, but I want to develop a platform where you can easily find and view f ...

What is the ternary operation syntax for setting the img src attribute in Angular 8?

My data includes a property called "photo" which can either have a file name or be empty. For instance, it could be "steve.jpg" or just an empty string if Steve does not have a photo. In React JSX, I know how to use a ternary operator with the "photo" va ...

The error message "Each item within a list must be assigned a unique 'key' prop" is being displayed

At the moment, I'm immersed in a project that utilizes React, Next.js, and Ant-Design. However, during the development process, I encountered an error due to the absence of a unique key like so: Here's the detailed log of the error: Warning: Ea ...

Enhancing interactivity: Implementing a ripple effect for Card clicks in Material UI

I'm curious if there's a method to incorporate a ripple effect into Material UI's Card component when it is clicked. Additionally, I am wondering if it is achievable to have the ripple effect display on top of the content within the Card co ...

Try utilizing a variety of background hues for uib progressbars

Looking to incorporate the ui-bootstrap progressbar into my template in two different colors, background included. My initial idea was to stack two progress bars on top of each other, but it ended up looking too obvious and messy, especially in the corner ...

Restricting the scope of reactivity in a VueJS data store

Goal: I am attempting to create an array of objects retrieved through an API call. After making the initial API call and receiving a single object, I want to store that result and then make another call without updating the original stored object. Challen ...

In order to have the bot repeat a structure for every user, I would need to utilize both mongoose and discord.js

I am utilizing MongoDB (mongoose) to establish a database for storing user notes in my Discord bot, which is being developed with Discord.JS. This is my "Guild.js" file: const { Schema, model } = require('mongoose'); const Guild = Schema({ i ...

Uploading and saving data to an object in FaunaDB using React hook forms

I am currently facing an issue with uploading/saving data to an object in FaunaDB. Specifically, I am trying to upload a string to a jobProfile object: data: { "jobProfile": { "image": "" "coverImage": " ...

Switch up the font style of the title element

Is it possible to modify the font-family of the title attribute in an input field using either JavaScript or jQuery? <input type="text" title="Enter Your Name" id="txtName" /> ...

When the clearOnBlur setting is set to false, Material UI Autocomplete will not

I recently encountered an issue in my project while using Material UI's Autocomplete feature. Despite setting the clearOnBlur property to false, the input field keeps getting cleared after losing focus. I need assistance in resolving this problem, an ...

Why does e.target.value only capture the initial letter of a string input in ReactJS?

Is the current method correctly capturing only the first letter in the string input? class Example extends React.Component{ state={ name:'Ajith' } changeEvent = (e) => { console.log('change : '+this.s ...

Searching for a specific element in jQuery by querying a string

I have a situation where an ajax request is made to send text using the POST method to another PHP page. This PHP page then converts the text into markdown format and sends it back. Here's an example of what it looks like: "<p>Meep, meep, <e ...

The Chip Component in MUI dynamically alters its background color when it is selected

Currently, I am working on a project in React where I am utilizing the MUI's Chip component. My goal is to customize this component so that it changes its background color when selected, instead of sticking to the default generic color. https://i.sta ...

Guide on how to trigger a pop-up modal to open a new webpage by clicking on a hyperlink

I have a page called one.html that has a link on it <a href="#">Click to open second page<a/> When this link is clicked, I would like for second.html to open in a popup modal. The second page contains a basic table that I want to di ...

Acquiring data from an API response in JSON format using JavaScript

Utilizing a parse.com API server, I have successfully established communication in JavaScript through AJAX. The output from the response is being logged into the browser console with the following code: $.ajax(settings).done(function(response) { ...

Utilize jQuery script on every single element

Is there a way to implement a jquery function on elements that are dynamically loaded via ajax? <span class="h">Test</span><br /><br /> <span class="h">Test</span><br /><br /> <span class="h">Test</ ...

Resolving unexpected behavior with res.locals and pug integration

I have a function in my app.js that allows the user-id to be accessible in pug templates. app.use(function (req, res, next) { res.locals.currentUser = req.session.userId; next(); }); When logged in, I can access the id. However, when not logged in, t ...

Innovative functionality for adding and deleting elements in JQuery/JavaScript

Is there a way to dynamically add and remove items when the Append/Clear buttons are clicked using this code snippet? $("#btn1").click(function(){ $("ul").prepend("<li>List Item</li>"); }); $("#btn2").click(function(){ $("ul").remove ...

Offspring maintain a certain position within the larger framework of their parent on a

When resizing the parent wrap container, how can I ensure that the pin (red dot) on the image maintains its relative position? To see the issue, resize the wrap container. #wrap{ position: absolute; width: 100%; height: 100%; top: 0; l ...