"Cannot read property parentNode" error

Hi, I have a simple component

<template>
  <div v-if="error"> {{ error }} </div>
  <i class="icon-bell"></i>
  <span class="count-icon" v-if="notificationsCount"> {{ notificationsCount }} </span>
</template>

<script>
import useNotifications from '@/modules/notifications';
import { computed } from 'vue';

export default {
  name: 'Notifications',
  async setup() {
    const {notifications, error, loading, loaded, load } = useNotifications();

    load();
    const notificationsCount = computed(() => ((notifications.value.data) ? notifications.value.data.length : 0));

    return {
      notifications,
      notificationsCount,
      error,
    };
  },
};
</script>

and error in console

Uncaught (in promise) TypeError: Cannot read property 'parentNode' of null

How to fix it?

I would start by looking through the stack trace to get a sense of what was going on and where the problem might be.

I suspect we’ll need to see what’s in useNotifications.

Is there any reason why you’re using async with setup?

useNotifications working well, it called in some different components, but only one component generate error.
oh, there must be await on load() calling, but that doesn’t solve the problem

Could you provide the full stack trace?

Given the mention of parentNode in the error message, my only guess would be that it is somehow related to the use of fragments in the template. That’s the only thing I can see that might somehow lead to a problem with parentNode. That’s a long shot though, it’s more likely the problem lies elsewhere.

I have same problem too. I’m using async on setup and every time I click on other links, it gives this “Cannot read property ‘parentNode’ of null”. I think async on setup() causes the problem because template doesn’t render too even if i use suspense boundary.

@AIM @McLotos I’m running into the same problem, did any of you figure it out?.

I have the same problem. As soon as I make setup() async it breaks routing.

I gave this a go and was able to reproduce it by combining the comments on this thread.

The key factors seem to be using async with setup on a component rendered by a <router-view>. The component itself doesn’t show up and trying to navigate to another page throws the error.

The simplest solution is to get rid of the async. Unless you’re trying to delay the setup process that’s the way to go.

If you want to use async with setup then you also have to use <suspense>. As <suspense> is an experimental feature you should prepare yourself for things going wrong and the API changing.

I could get it to work using this:

<router-view v-slot="{ Component }">
  <suspense>
    <component :is="Component" />
  </suspense>
</router-view>

That code comes from here:

https://github.com/vuejs/vue-next/issues/2143#issuecomment-694640896

As someone has noted on that thread, even with this code you’ll get a warning that <Suspense> slots expect a single root node. That warning appears to be incorrect and you should find that everything works fine. In my experiments I found that I could make that warning go away by wrapping the <component> in an extra <div> so that the <suspense> had a fixed, immediate child.

1 Like