2

My Problem

I am trying to store a list of complex items in a store and access these items from a component. I have a mqtt interface which receives data for these items and updates their values in the store. However, the ui does not react to updating the properties of these items.

Structure

In my store, i have two mutations:

state: {
  itemList:{}
},
mutations: {
  /// adds a new item to itemList
  [ADD_ITEM](state, item) {
    if (item&& !state.itemList[item.itemId])
    {
      Vue.set(state.itemList, item.itemId, item);
    }
  },
  /// updates an existing item with data from payload
  [SET_ITEM_STAT](state, { itemId, payload }) {
    var item= state.itemList[itemId];
    if (item) {
      item.prop1 = payload.prop1;
      item.prop2 = payload.prop2;
    } 
  }
},
actions: {
  /// is called from outside once when connection to mqtt (re-)established
  initializeMqttSubscriptions({ commit, dispatch }, mqtt){
    mqtt.subscribeItem("items/stat", async function(itemId, topic, payload) {
      commit(SET_ITEM_STAT, { itemId, payload });
    });
  },
  ...
}

I also tried:

  • setting the item properties using Vue.set(state.itemList, itemId, item);
  • setting the item properties using Vue.set(state.itemList[itemId], 'prop1', payload.prop1);

I also want to show how i built the Component which accesses and displays these items (Item.vue). It is one component, that gets passed the itemId to show via the route params. I've got the following computed properties:

<template>
<div class="grid-page">
    <h1 class="page-title">Item- <span class="fw-semi-bold">{{ id }}</span></h1>
    <div>
        <Widget v-if="item">
            {{ item.prop1 }}
...
...
computed: {
  id(){
    return this.$route.params.itemId;
  },
  item(){
    return this.$store.state.items.itemList[this.id];
  }
}

So when the route parameter itemIdchanges, i successfully can see the item data, everything is fine. But if i update the properties of an item with the mutation shown above, no update in view is triggered.

I would be very happy if someone could give me a hint what i am doing wrong here. Thanks in advance!

1 Answer 1

1

Since i can't comment to ask for some clarifications,

If you're itemlist is an nested object, try out with Object.assign


[SET_ITEM_STAT](state, { itemId, payload }) {
    var item= state.itemList[itemId];
    if (item) {
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId].prop1, {payload.prop1})
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId].prop2, {payload.prop2})

// or
this.state.itemList[itemId] = Object.assign({}, this.state.itemList[itemId], {prop1: payload.prop1, prop2: payload.prop2})
    } 
  }

Let me know how it goes

https://v2.vuejs.org/v2/guide/reactivity.html#For-Objects

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

2 Comments

Thanks Dario, that solved my problem! I had tried creating a new instance using the spread syntax, but i understand now, that this did not really create a deep copy of the item. Thanks again!
Pleasure to help :)

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.