mstdmstd
mstdmstd

Reputation: 3081

Why content of child component with props is not rendered on the page?

In vuejs3 app I read data with axios request from backend API. I see that data are passed to internal component, but I do not see content of the child component is rendered on the page.

Parent component:

<template>
      <div class="row m-0 p-0" v-show="forumCategories.length && isPageLoaded">
        <div v-for="(nextActiveForumCategory, index) in forumCategories" :key="nextActiveForumCategory.id" class="col-sm-12 col-md-6 p-2 m-0">
          index::{{ index}}
          <forum-category-block
            :currentLoggedUser="currentLoggedUser"
            :nextActiveForumCategory="nextActiveForumCategory"
            :index="index"
            :is_show_location="true"
          ></forum-category-block>
        </div>
      </div>
</template>

<script>
  import ForumCategoryBlock from '@/views/forum/ForumCategoryBlock.vue'
  import { useStore } from 'vuex'

  export default {
    
    name: 'forumsByCategoryPage',

    components: {
      ForumCategoryBlock,
    },

    setup () {
      const store = useStore()
      const orderBy = ref('created_at')
      const orderDirection = ref('desc')

      const forumsPerPage = ref(20)
      const currentPage = ref(1)
      let forumsTotalCount = ref(0)
      let forumCategories = ref([])
      let isPageLoaded = ref(false)
      let credentialsConfig = settingCredentialsConfig

      const currentLoggedUserToken = computed(
        () => {
          return store.getters.token
        }
      )

      const currentLoggedUser = computed(
        () => {
          return store.getters.user
        }
      )
      
      const forumsByCategoryPageInit = async () => {
        loadForums()
      }
      
      function loadForums() {
        isPageLoaded = false
        let credentials = getClone(credentialsConfig)
        credentials.headers.Authorization = 'Bearer ' + currentLoggedUserToken.value
        let filters = { current_page: currentPage.value, order_by: orderBy.value, order_direction: orderDirection.value }
        const apiUrl = process.env.VUE_APP_API_URL

        axios.get(apiUrl + '/forums-by-category', filters, credentials)
          .then(({ data }) => {
            console.log('/forums-by-category data::')
            console.log(data)

            forumCategories.value = data.forumCategories
            forumsTotalCount.value = data.forumsTotalCount
            isPageLoaded = true
            console.log('++forumCategories::')
            console.log(forumCategories)
          })
          .catch(error => {
            console.error(error)
            isPageLoaded = true
          })
      } // loadForums() {

      onMounted(forumsByCategoryPageInit)
      
      return {
        currentPage, orderBy, orderDirection, isPageLoaded, loadForums, forumCategories, getHeaderIcon, pluralize, forumsTotalCount, forumCategoriesTitle, currentLoggedUser
      }
    } // setup
</script>

and ForumCategoryBlock.vue:

<template>
  <div class="">
    <h1>INSIDE</h1>
    <fieldset class="bordered" >
      <legend class="blocks">Block</legend>
      nextActiveForumCategory::{{ nextActiveForumCategory}}<br>
      currentLoggedUser::{{ currentLoggedUser}}<br>
      index::{{ index }}<br>
    </fieldset>
  
  </div>
</template>

<script>
  import { computed } from 'vue'
  export default {
    name: 'forumCategoryBlock',

    props: {
      currentLoggedUser: {
        type: Object,
        default: () => {}
      },
      nextActiveForumCategory: {
        type: Object,
        default: () => {}
      },
      index: {
        type: Number,
        default: () => {}
      }
    },

    setup (props) {
      console.log('setup props::')
      console.log(props)
      const nextActiveForumCategory = computed({
        get: () => props.value.nextActiveForumCategory
      })
      const currentLoggedUser = computed({
        get: () => props.value.currentLoggedUser
      })
      const index = computed({
        get: () => props.index
      })
      return { /* currentLoggedUser, nextActiveForumCategory, index */ }
    }

  }
</script>

What I see in browser : https://prnt.sc/vh7db9

What is wrong abd how to fix it ?

MODIFIED : I understood WHERE the error :

  <div class="row m-0 p-0" v-show="forumCategories.length  && isPageLoaded" style="border: 2px dotted red;">

if to remove 2nd condition && isPageLoaded in a line above I see content.

But looks like that var isPageLoaded is not reactive and I do not see why? If is declared with ref and is declared in return of setup method. But looks like as I modify it in loadForums method it does not work in template... Thanks!

Upvotes: 0

Views: 50

Answers (1)

tony19
tony19

Reputation: 138306

isPageLoaded is losing its reactivity because loadForums() is changing its type from ref to Boolean:

isPageLoaded = true // ❌  no longer a ref

isPageLoaded is a ref, so your code has to access it through its value property. It's probably best to use const instead of let here to avoid this mistake:

const isPageLoaded = ref(false)
isPageLoaded.value = true // ✅

Upvotes: 1

Related Questions