inertia: Error when updating the list on consecutive page reload

Versions:

  • @inertiajs/inertia version: 0.8.6
  • @inertiajs/inertia-vue3 version: 0.3.12
  • inertiajs/inertia-laravel version 0.3.6

Describe the problem:

I’ve a checkbox on the page and a watcher that reloads the page with filtered data based on it’s value, I’m getting following error when Inertia reloads the page second time and element list in the DOM is being updated:

app.js:12889 Uncaught (in promise) TypeError: Cannot read property 'insertBefore' of null
    at insert (app.js:12889)
    at mountElement (app.js:9604)
    at processElement (app.js:9545)
    at patch (app.js:9465)
    at patchKeyedChildren (app.js:10210)
    at patchChildren (app.js:10093)
    at processFragment (app.js:9839)
    at patch (app.js:9461)
    at patchKeyedChildren (app.js:10174)
    at patchChildren (app.js:10117)

Steps to reproduce:

  1. Have a page with it’s content wrapped within layout component. (Using persistent layout fixes the problem)
  2. Have an element that that triggers page reload with new data based on some property
  3. Have a deeply nested list of data with v-for loop. (Moving the loop one level up in my example fixes the problem). I’ve tried keying element by object id (in my real app) , by index or just by numeric value but that does not help.
  4. Trigger page reload several times. (In my example error occurs on second reload) That’s my test component recreated in new Laravel Breeze with Inertia template - resources/js/Pages/Welcome.vue
 <template>
  <guest>
      <div>
          <div class="mt-2 text-right">
              <label class="inline-flex items-center leading-none">
                  <input v-model="checkBox" type="checkbox" class="mr-2" />
                  <span>Test checkbox</span>
              </label>
          </div>
          <div>
              <div v-for="value in someData" :key="value">
                  {{value}}
              </div>
          </div>
      </div>
  </guest>
  </template>
  
  <script>
      import Guest from "../Layouts/Guest";
      import {ref, watch} from "vue";
      import { Inertia } from '@inertiajs/inertia';
      export default {
          components: {Guest},
          props: {
              someData: {
                  type: Array,
                  required: true,
              }
          },
          setup() {
              const checkBox = ref(false);
              watch(checkBox, (value) => {
                  Inertia.reload({ data: { test: value ? 1 : 0 } });
              });
              return {checkBox}
          }
      }
  </script>

That is the test route I’m using:

Route::get('/', function () {
    return Inertia::render('Welcome', [
        'someData' => request()->input('test') === '1' ? [1, 2, 3] : [1, 2, 3, 4, 5, 6],
    ]);
});

Demo repository: https://github.com/bakanyaka/inertia-vue-bug

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 7
  • Comments: 16 (5 by maintainers)

Most upvoted comments

Hey thanks for providing a nice demo repo for this. I just spent almost an hour trying to figure out what’s going on here, and I honestly don’t know. I’m starting to think this is a Vue bug, as the error suggests:

image

One thing that did work for me was to wrap the page component in an extra <div>:

 <template>
  <div>
    <guest>
      ...
    </guest>
  </div>
</template>

The fact that this works, makes me think this is an issue with the new fragments feature in Vue 3.

I am sorry I cannot be more helpful than that. I am going to close this issue, as I don’t think it’s an Inertia bug, but if anyone can prove otherwise, feel free to post, and we can reopen. 👍

For anyone browsing this issue, here is exactly how I fixed it (as others mention above, but without examples):

Before:

<!-- pages/Home.vue -->

<template>
    <layout>
        ...content
    </layout>
</template>

After:

<!-- pages/Home.vue -->

<template>
    <div>
        <layout>
            ...content
        </layout>
    </div>
</template>

Hoping I don’t have to do this with every page…

FWIW - I ran into this today as well, using JetStream (which I guess is fair to assume others are too).

Adding a wrapping <div> around <app-layout> worked for me too… odd!

I am having this exact same issue. I also get this issue using “this.$inertia.reload({ only: [‘users’]})” on a axios request. I don’t get any errors if I add a redirect to a different page, however if I remain on the same page that error occurs.

edit: I tried adding an extra div around my component as reinink suggested and it still wasn’t working. I had to add an extra div around the layout component. 🤯🤯

Hi @reinink I think @bakanyaka worry is fixed. I’ve got same worry and update vue dep on project.

In vue@3.1.5, bug is fixed. For information, I’ve search for issue mentionning that.

Pretty sure it has something todo with scoped slots.

https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots

Solved it myself by passing the data that was not being reactive inside the slot, which in your case is <guest>

Took me 5 hours to figure out grrrr

image