Duplicate array items in Vuex state (using Socket.io)

Viewed 166

So I have this app built in Vue and using Vuex. I connect to a Node/Express backend with Socket.Io to be able to push data from the server to client instantly when needed.

The data pushed to the clients are in the form of an object which is then stored in an array in VUEX. Each data object pushed into the array has a unique string attached to it.

This string is used to compare the objects already pushed into the array in VUEX. If there are duplicates they won't be stored. If not equal = they are stored.

I then use ...mapGetters to get the array in Vuex and loop through it. For each object a component is rendered.

HOWEVER - sometimes the same object is rendered twice even though the array in VUEX clearly only shows one copy.

Here is the code in the VUEX Store:

export default new Vuex.Store({
  state: {
    insiderTrades: [],
  },

  mutations: {
    ADD_INSIDER_TRADE(state, insiderObject) {
      if (state.insiderTrades.length === 0) {
        // push object into array
        state.insiderTrades.unshift(insiderObject);
      } else {
        state.insiderTrades.forEach((trade) => {
          // check if the insider trade is in the store
          if (trade.isin === insiderObject.isin) {
            // return if it already exists
            return;
          } else {
            // push object into array
            state.insiderTrades.unshift(insiderObject);
          }
        });
      }
    },
  },
  getters: {
    insiderTrades(state) {
      return state.insiderTrades;
    },
  },

Here is the some of the code in App.vue

mounted() {
  // //establish connection to server
  this.$socket.on('connect', () => {
    this.connectedState = 'ansluten';
    this.connectedStateColor = 'green';
    console.log('Connected to server');
  });
  //if disconnected swap to "disconneted state"
  this.$socket.on('disconnect', () => {
    this.connectedState = 'ej ansluten';
    this.connectedStateColor = 'red';
    console.log('Disconnected to server');
  });
  // recieve an insider trade and add to store
  this.$socket.on('insiderTrade', (insiderObject) => {
    this.$store.commit('ADD_INSIDER_TRADE', insiderObject);
  });
},
1 Answers

Your forEach iterates the existing items and adds the new item once for every existing item. Use Array.find:

ADD_INSIDER_TRADE(state, insiderObject) {
  const exists = state.insiderTrades.find(trade => trade.isin === insiderObject.isin);
  if (!exists) state.insiderTrades.unshift(insiderObject);
},

You don't need the initial length check

Related