Dialog box doesn't render while a pinia property was correctly togg

135 views Asked by At

I’m still learning using Vue 3 and Pinia. My program has a main component with a template that shows/hides a modal according to the value of a store boolean property called PlaceModalStore.isShown. In the main component, a ref called isShown takes reactively the same value of the property: const { isShown } = storeToRefs(PlaceModalStore) This ref is used in a v-if statement in the template of main component to show/hide the modal dialog box.

<teleport to="body">
    <transition name="fade">
        <PlaceTemplate v-if="isShown"/>
    </transition>
</teleport>

If I set this initial value of PlaceModalStore.isShown to true

export const usePlaceModalStore = defineStore('PlaceModalStore', {
    state: () => ({
        isShown: true,
...
}

the modal dialog box is rendered and I can make it go by clicking on a button: @click=”PlaceModalStore.setPlaceModalHide”. This toggles the value of PlaceModalStore.isShown to false. A watcher shows the ref isShown was toggled to false as expected. Everything seems fine but…

If I set the initial value of PlaceModalStore.isShown to false in state:() ..., the JS module runs and when the dialog box shall renders it calls PlaceModalStore.setPlaceModalShow that sets PlaceModalStore.isShow to true. A console.log statement shows this was correctly changed, but… the watcher doesn’t catch it and the modal dialog box is not rendered.

The store was created in main.js as follows:

const PlaceModalStore = usePlaceModalStore()

The code for the store is as follows:

import { defineStore } from 'pinia'

export const usePlaceModalStore = defineStore('PlaceModalStore' /* the unique ID */, {
  state: () => ({
    isShown: true,
    userHasSkipped: false,
    index: 0,
    message:
      'The location where the event occured was not found in my database. I was only able to determine the country name. Would you mind completing the information?',
    fullPlace: 'Porto Empedocle, UNK, Sicilia, Italia', // For testing
    city: 'Porto Empedocle', // For testing
    county: 'Agrigento', // For testing
    region: 'Sicilia', // For testing
    country: 'Italia', // For testing
  }),
  actions: {
    setPlaceModalShow() {
      this.isShown = true
      console.log("setPlaceModalShow() says PlaceModalShow changed to 'true'")
    },
    setPlaceModalHide() {
      this.isShown = false
      this.userHasSkipped = false
      console.log("setPlaceModalHide() says PlaceModalShow changed to 'false'")
    },
    setPlaceModalSkip() {
      this.isShown = false
      this.userHasSkipped = true
    },
    setPlaceModalContent(index, message, fullPlace, city, county, region, country) {
      this.index = index
      this.message = message
      this.fullPlace = fullPlace
      this.city = city
      this.county = county
      this.region = region
      this.country = country
    }
  }
})

Here is the call from the JS module is as simple as:

PlaceModalStore.setPlaceModalShow()

Thank for your help.

Edit-- It seems that the property PlaceModalStore.iShown might not be reactive. The console doesn't output anything after inserting this line in the main component.

watch(
  () => PlaceModalStore.isShown, (newValue) => {
     console.log('watch says property "isShown" has changed to: ', newValue);
  }
)
1

There are 1 answers

4
nom_unique On

Working solution with

const PlaceModalStore = usePlaceModalStore();
const isShown = computed(() => PlaceModalStore.isShown);
// You can use isShown in your template

You'll find other answers here: https://stackoverflow.com/a/76131716/12665127