Inertia: Error when updating the list on consecutive page reload

Created on 8 Apr 2021  路  5Comments  路  Source: inertiajs/inertia

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

Most helpful comment

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. 馃憤

All 5 comments

I am also having this problem :/

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. 馃憤

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

Took me 5 hours to figure out grrrr

image

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. 馃く馃く

@akc4 The issue is that your code is running in a vue slot inside app-layout. You have to v-bind your data to app-layout like I've done in the screenshot above if you want to make it reactive.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebastiandedeyne picture sebastiandedeyne  路  3Comments

MichaelDeBoey picture MichaelDeBoey  路  4Comments

kufdaw picture kufdaw  路  6Comments

kirrg001 picture kirrg001  路  6Comments

JoeCianflone picture JoeCianflone  路  4Comments