Search code examples
javascriptvue.jsvuejs3vue-componentvuejs3-composition-api

Question about vue 3 lifecycle and availability of properties


I want to load some content of a vue component based on a given argument. Here is some code to illustrate:

ParentComponent.vue

<Suspense>
<div class="row g-0">
  <div class="col-md-3">
    <ChildComponent json-url="some/url/to/json/data" />
  </div>
  <div class="col-md-3">
    <ChildComponent json-url="some/url/to/json/data" />
  </div>
  <div class="col-md-3">
    <ChildComponent json-url="some/url/to/json/data" />
  </div>
  <div class="col-md-3">
    <ChildComponent json-url="some/url/to/json/data" />
  </div>
</div>

<template #fallback>
  <p>Loading...</p>
</template>

ChildComponent.vue

<template>
 <!-- some content based on the loaded json data -->
</template>

<script setup>
  import { ref, onMounted} from 'vue';
  

  defineProps({jsonUrl: {
    type: String,
    default: ""
  }})
  const images = ref(null);
  const thumbnail = ref(null);
  const title = ref("");
  const description = ref("");

  onMounted(async () => {
    try {
      const response = await fetch(new URL(jsonUrl, import.meta.url).href);
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      var jsonData = await response.json();

      images = jsonData["images"];
      thumbnail = jsonData["thumbnail"];
      title = jsonData["title"];
      description = jsonData["description"];
      console.log(thumbnail);
      
    } catch (error) {
      console.error('Error fetching the JSON file:', error);
    }
  });

</script>

The problem is that jsonUrl does not seem to be available during the onMounted() callback. Naming and everything should work, since if I simply put <p>{{json}}</p> into the template it shows the urls correctly.

I have searched around a bit, but it seems the property should be available? For example, this post answer shows pretty much the same approach (only difference being the usage of typescript). How can I correctly load and initialize my content based on the json data within my child component here?


Solution

  • When using setup, you have to define the props variable:

    const props = defineProps({jsonUrl: {
      type: String,
      default: ""
    }})
    

    Then use props.jsonUrl to access the prop. This should allow you to access the prop inside of onMounted