Search code examples
vue.jsaxiosvue-composition-api

Vue 3 Uncaught (in promise) TypeError: parent is null - Composition API


I have a component with setup and using composition API. On mounted, I make a call to server and while the call is waiting for the request I show a loading icon. For some weird reason, I get this error message

Uncaught (in promise) TypeError: parent is null

My Code is setup like this:

<script setup>
import {useRoute} from "vue-router";
import {onMounted, reactive, ref} from "vue";
import axios from "axios";
const subject = ref("");
const isLoading = ref(true);

onMounted( async function () {
    await axios.get('/mycallurl/something' + route.params.uuid}).then((res) => {
        subject.value = res.data.subject; //a string
       isLoading.value = false;
    });
});

I have tried to set the isLoading value in a second "then" like this,

onMounted( async function () {
    await axios.get('/mycallurl/something' + route.params.uuid}).then((res) => {
        subject.value = res.data.subject; //a string
    }).then(()=>{isLoading.value = false; });
});

I also tried initializing isLoading as null like isLoading = ref(null);

all of which bring the error.

It only works when I put isLoading.value = false; after the onMounted() block like:

onMounted( async function () {
    await axios.get('/mycallurl/something' + route.params.uuid}).then((res) => {
       subject.value = res.data.subject; //a string
}).then(()=>{isLoading.value = false; });
});

setTimeout(function(){

  isLoading.value = false;

}, 2000); //assuming after 2 secs the request has succeeded

I have banged my head and tried a few things and after 1 hr I would appreciate any insights on this!


Solution

  • The issue was simply moving the v-if condition to a parent div and not the actual icon.

    From

    <template>
      <div>
        <i class="fa fa-spinner fa-spin" v-if="isLoading"></i>
      </div>
    </template>
    

    To

    <template>
      <div  v-if="isLoading">
        <i class="fa fa-spinner fa-spin"></i>
      </div>
    </template>
    

    if I have the time I will dig deeper, but this is what ended up working