Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: this.inputElement is null #417

Closed
tbl0605 opened this issue Apr 14, 2021 · 1 comment · Fixed by #432
Closed

TypeError: this.inputElement is null #417

tbl0605 opened this issue Apr 14, 2021 · 1 comment · Fixed by #432
Assignees
Labels
bug Something isn't working patch This is a thing to include in the next patch
Projects
Milestone

Comments

@tbl0605
Copy link
Contributor

tbl0605 commented Apr 14, 2021

Hi,
I'm getting a "TypeError: this.inputElement is null" error when using vue-simple-suggest on custom inputs and using Webpack's lazy loading globally (in "eager" mode) with prefetch disabled.
The bug occurs only the first time a view component is used (because of lazy loading), further instances seem to work correctly.

The problem is (somehow) also described here: https://forum.vuejs.org/t/not-getting-refs-in-mounted/12490
The root cause is that $refs is not always available in the mounted lifecycle hook.

I've created a projet to easily reproduce this issue (see the README.md file of the project for more details) :
https://github.com/tbl0605/vue-bug-simple-suggest

So basically this bug appears (for me) when:

  • using "eager" mode on vue-router routes
component: () => import(/* webpackMode: "eager" */ './views/MyView.vue')
  • disabling prefetch in vue.config.js
config.plugins.delete('prefetch');
  • using dynamic component loading
const componentContext = require.context(
  '@/components',
  true,
  /\w\d*\.vue$/i,
  'eager'
);
componentContext.keys().forEach(componentFilePath => {
  const componentName = upperFirst(
    camelCase(
      componentFilePath
        .split('/')
        .pop()
        .replace(/\.vue$/, '')
    )
  );
  const componentContent = componentContext(componentFilePath);
  const componentConfig = componentContent.default || componentContent;
  if (componentConfig instanceof Promise) {
    Vue.component(componentName, () => componentConfig);
  } else {
    Vue.component(componentName, componentConfig);
  }
});

Workaround:

I've patched the mounted method in vue-simple-suggest.vue to delay initialization to be done after the first component rendering:

  mounted () {
    setTimeout(() => {
      this.inputElement = this.$refs['inputSlot'].querySelector('input')
      this.setInputAriaAttributes()
      this.prepareEventHandlers(true)
    }, 0)
  }

Maybe it can be done otherwise, but in my case, it works well ;)

@kaskar2008
Copy link
Member

Hello, @tbl0605!

Thank you for this bug report. Sorry for the long reply.

@kaskar2008 kaskar2008 self-assigned this May 4, 2021
kaskar2008 added a commit that referenced this issue May 4, 2021
@kaskar2008 kaskar2008 added this to the 1.10 milestone Jun 1, 2021
@kaskar2008 kaskar2008 added this to To do in Fixes via automation Jun 1, 2021
@kaskar2008 kaskar2008 added bug Something isn't working patch This is a thing to include in the next patch labels Jun 1, 2021
@kaskar2008 kaskar2008 moved this from To do to Done in Fixes Oct 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working patch This is a thing to include in the next patch
Projects
Fixes
  
Done
Development

Successfully merging a pull request may close this issue.

2 participants