Search code examples
vue.jsvuejs2vue-componentvuexcomputed-properties

How to watch for a value which depends on another value vue?


First off, sorry for the vague title; I couldn't come up with a really succinct one. Here's my situation:

Let's say I have users, topics and comments in a vuex store. Users have names, a list of topics as well as the topic they have currently selected:

users: {
  1: { 
      name: 'Tom',
      topics: [1, 2],
      selectedTopic: null // set to 1 and then 2 when user clicks "next"
    },
  2: {... }
},
topics:
  1: { 
      title: 'Post!',
      comments: [1, 2],
      selectedComment: null
    },
  2: { ... }
},
comments:
  1: { 
      title: 'Cool!'
    },
  2: { ... }
}

If a user is selected, I want to show their name. If a user also selects a topic, this topic should be displayed as well; they can also cycle through the topics. For every topic, they can cycle through the comments in the same way. Thus:

computed: {
  // some getters
  // ...
  user () {
    return this.getUser(this.userId)
  },
  topic () {
    return this.getTopic(this.user.topics[this.user.selectedTopic])
  },
  comment () {
    return this.getComment(this.topic.comments(this.topic.selectedComment])
  }

In this case, the cycling works, but the console shows a TypeError: "this.user.topics is undefined" or "this.user.selectedTopicis undefined" at the start (only sometimes), which is true, of course, since we haven't selected a user yet. On the other hand, if I replace this with

  topic () {
    if (this.user) return this.getTopic(this.user.topics[this.user.selectedTopic])
  }

I don't get any errors, but neither does the value update when the selected topic is changed. Is there a good way to handle the issue?


Solution

  • Based on a comment by Ivo Gelov, I arrived at

    return this.getTopic((this.user.topics || {})[this.user.selectedTopic])

    This seems to do the trick.