quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.9k stars 3.51k forks source link

use-virtual-scroll.js #13231

Closed qxygene closed 2 years ago

qxygene commented 2 years ago

What happened?

Uncaught TypeError: Cannot read properties of null (reading 'children') at eval (use-virtual-scroll.js?4f3e:28:1)

What did you expect to happen?

Using select component with filter, when serch no match getting an error.

  `const children = contentEl.children || []`

Reproduction URL

https://codesandbox.io/s/awesome-cray-f483ed?file=/src/components/test.vue

How to reproduce?

Uncaught TypeError: Cannot read properties of null (reading 'children') at eval (use-virtual-scroll.js?4f3e:28:1)

Flavour

Quasar CLI with Webpack (@quasar/cli | @quasar/app-webpack)

Areas

Components (quasar)

Platforms/Browsers

Chrome

Quasar info output

Operating System - Windows_NT(10.0.22000) - win32/x64
NodeJs - 16.14.0

Global packages
  NPM - 7.18.1
  yarn - Not installed
  @quasar/cli - 1.3.2
  @quasar/icongenie - Not installed
  cordova - Not installed

Important local packages
  quasar - 2.6.6 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
  @quasar/app-webpack - 3.5.1 -- Quasar Framework App CLI with Webpack
  @quasar/extras - 1.13.5 -- Quasar Framework fonts, icons and animations
  eslint-plugin-quasar - Not installed
  vue - 3.2.29 -- The progressive JavaScript framework for building modern web UI.
  vue-router - 4.0.14
  pinia - 2.0.13 -- Intuitive, type safe and flexible Store for Vue
  vuex - Not installed
  electron - Not installed
  electron-packager - Not installed
  electron-builder - Not installed
  @babel/core - 7.17.8 -- Babel compiler core.
  webpack - 5.70.0 -- Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
  webpack-dev-server - 4.8.1 -- Serves a webpack app. Updates the browser on changes.
  workbox-webpack-plugin - Not installed
  register-service-worker - 1.7.2 -- Script for registering service worker, with hooks
  typescript - 4.5.5 -- TypeScript is a language for application scale JavaScript development
  @capacitor/core - Not installed
  @capacitor/cli - Not installed
  @capacitor/android - Not installed
  @capacitor/ios - Not installed

Quasar App Extensions
  *None installed*

Networking
  Host - LAPTOP-KP9Q1DUM
  VMware Network Adapter VMnet1 - 192.168.62.1
  VMware Network Adapter VMnet8 - 192.168.100.1
  Wi-Fi - 192.168.1.45

Relevant log output

No response

Additional context

No response

JamieMcDonnell commented 2 years ago

Also experiencing this when I clear the filter which drives the options computed object. Any ideas of a timeframe for this one as it is causing an issue in my customer-facing production build of https://converso.io

Thanks @pdanpdan ;)

pdanpdan commented 2 years ago

fixed in Qv2.7.0/Qv1.19.0

lavoscore commented 2 years ago

I can see this still happening as of 2.10.0 when working with a QSelect with remote options from an API.

Cannot read properties of null (reading 'children')

pdanpdan commented 2 years ago

Please create a reproduction codepen

lavoscore commented 2 years ago

Tried to fork from the Lazy Filtering example, but couldn't reproduce the error. However, I found out that it happens when I assign an empty list to my options:

const options = ref([]) // passed as :options to my q-select
const filter = (val, update, abort) {  // passed as @filter to my q-select
  update(async () => {
    if (val === '') {
      options.value = [] // <-- error
    } else {
      options.value = await myRemoteApiMethod(val) || [] // <-- will get the error if no matches are found
    }
  })
},

Also, the error doesn't happen if I don't provide a no-option slot to the select.

pdanpdan commented 2 years ago

You're holding async/await the wrong way :) The update function expect a sync function that updates the list of options - that is the reason for it, to be sure that when it ends the list of options is updated

const options = ref([]) // passed as :options to my q-select
const filter = async (val, update) => { // passed as @filter to my q-select
  const list = val === '' ? [] : await myRemoteApiMethod(val)

  update(async () => {
    options.value = list || []
  })
}
lavoscore commented 2 years ago

Nice catch, but unfortunately the bug stands. It fails when list is empty and the select has options. If I change your code to something like below, no error is raised:


const options = ref([]) // passed as :options to my q-select
const filter = async (val, update) => { // passed as @filter to my q-select
  const anything = { id: 123, name: 'Foo' }
  const list = val === '' ? [ anything ] : await myRemoteApiMethod(val)

  update(() => {
    options.value = list || [ anything ]
  })
}
pdanpdan commented 2 years ago

try to break it from this pen and post back the reproduction when you found the combination that breaks it https://codepen.io/pdanpdan/pen/ExLBGMg?editors=1010

lavoscore commented 2 years ago

There was no way I could break it 😞. As for my code, reduced it to the smallest (dummy data, no async) and updated vue to latest. I just can't clear existing options. Maybe some dependency is the cause?

const filter = (val, update) => {
  update(() => {
    options.value = val === '' ? [] : [ { id: 123, name: 'Foo' } ] // still hit the error if val is empty and options.value is non-empty
  })
}

I have no more ideas. I'll post here if I find anything. Thanks!

pdanpdan commented 2 years ago

What do you mean by "I just can't clear existing option"?

lavoscore commented 2 years ago

Sorry, they get cleared yes, but the console prints "Cannot read properties of null (reading 'children')".

For my latest code above, my steps are:

pdanpdan commented 2 years ago

Ok, I'll check these steps tomorrow

pdanpdan commented 2 years ago

Sorry, I cannot reproduce your situation - maybe you have some options in QSelect? Please make a codepen with your situation