1

I have a property of type Boolean - websiteHasCode which takes a value from store. I want to render html in the page conditionally using websiteHasCode ( true or false ) , Initially the component A is fine ( correct value for websiteHasCode ). There is a modal in the page , which is child component B of component A, The modal has the functinality of updating the store value - isCodeActive. So when it updates I want the variable websiteHasCode to also update and eventually the Dom, So I used a watcher and computed as in this SO question, But it doesn't seem to update. Can anyone help what i got wrong here ?

<template> 
  <div>
    <div v-if="websiteHasCode">
          ...............
    </div>
    <div v-else>
          ................
    </div>
  </div>
</template>


<script>
    export default {
        name: "dashboard",
        props: [],
        data() {
            return {
                websiteHasCode: Boolean,
            }
        },
        mounted() {
            this.websiteHasCode = this.$store.state.isCodeActive;
        },
        computed: {
          isCodeActive () {
            return this.$store.state.isCodeActive;
          }
        },
        watch: {
          isCodeActive: {
            handler() {
              console.log(this.websiteHasCode) // returns false
              this.websiteHasCode = this.$store.state.isCodeActive;
              console.log(this.websiteHasCode) // returns true but dom does not re-render
            },
            deep: true
          },
        },
      }
</script>

Also is this the best way to watch state changes , are there any better ways ?

theFrontEndDev
  • 890
  • 1
  • 17
  • 41
  • 1
    I'm not sure I understand what you want to do. Maybe it will help this.$forceUpdate() If not, it would help me if you would add code to codePen – Grzesiek Sep 07 '20 at 11:31
  • 2
    what about using `isCodeActive` directly like `
    `?
    – Sphinx Sep 07 '20 at 11:57
  • 1
    Also you should initialize the `websiteHasCode` property in the `data` function – sebasaenz Sep 07 '20 at 12:14
  • @Sphinx Do you mean like v-if="$store.state.isCodeActive" ? Its a value in store right ? – theFrontEndDev Sep 07 '20 at 12:30
  • @sebasaenz Sorry! missed that while copy pasting – theFrontEndDev Sep 07 '20 at 12:31
  • 1
    @theFrontEndDev no problem! I think Sphinx meant that you should use directly the computed property you declared as `isCodeActive` in the `v-if`. – sebasaenz Sep 07 '20 at 12:41
  • @sebasaenz Okay ! Got it , But when i used v-if="$store.state.isCodeActive", it's working fine, Is it a bad method to do that ? If that is the case I will use v-if="isCodeActive" – theFrontEndDev Sep 07 '20 at 13:07
  • @theFrontEndDev it's fine to do it that way but it's also a good practice to make it a computed property for more readability. Check also `mapState`. – sebasaenz Sep 07 '20 at 13:17

1 Answers1

1

Unless you want to do something else based on the value of isCodeActive, there's no point in using a watcher for the computed, just use the computed directly in your v-if like so:

<template> 
  <div>
    <div v-if="isCodeActive">
          ...............
    </div>
    <div v-else>
          ................
    </div>
  </div>
</template>
    

<script>
    export default {
        name: "dashboard",
        props: [],
        data() {
            return {
                websiteHasCode: Boolean, // not sure why you're initializing with "Boolean" here, it should be false
            }
        },
        computed: {
          isCodeActive () {
            return this.$store.state.isCodeActive;
          }
        },
      }
</script>

Also, you're initializing your websiteHasCode property as "Boolean' instead of false. Might be that vue sees this as a truthy value and does not update the layout because of that.