algolia / vue-instantsearch

πŸ‘€ Algolia components for building search UIs with Vue.js
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/vue
MIT License
853 stars 157 forks source link

vue-instantsearch not working in my VueJS 3.0 project #1071

Closed eugenevk closed 3 years ago

eugenevk commented 3 years ago

Bug 🐞 I have a VueJS 3.0 project (Options API) in combination with Firebase and Algolia. Everything works fine. I have multiple indices defined in Algolia and I can search them simultaneously with my own Vue code that I've written, but I would rather use vue-instantsearch from Algolia. I have tried to setup the basics to search one index (companyIndex), however I can't get it to work. Error I get is this (####### are my keys):

[Vue warn]: Unhandled error during execution of created hook 
  at <AisSearchBox> 
  at <AisInstantSearch search-client= {transporter: {…}, appId: '#########', addAlgoliaAgent: Ζ’, clearCache: Ζ’, search: Ζ’, …}addAlgoliaAgent: Ζ’ (e,t)appId: "#########"clearCache: Ζ’ ()initIndex: Ζ’ (t)multipleQueries: Ζ’ (t,n)multipleSearchForFacetValues: Ζ’ (t,o)search: Ζ’ (t,n)searchForFacetValues: Ζ’ (t,o)transporter: {hostsCache: {…}, logger: {…}, requester: {…}, requestsCache: {…}, responsesCache: {…}, …}[[Prototype]]: Object index-name="companyIndex" > 
  at <Home onAuthenticated=fn<setAuthenticatedUser> onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > > 
  at <RouterView onAuthenticated=fn<setAuthenticatedUser> > 
  at <App>
...
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next 
  at <AisSearchBox> 
  at <AisInstantSearch search-client= {transporter: {…}, appId: '#########', addAlgoliaAgent: Ζ’, clearCache: Ζ’, search: Ζ’, …} index-name="companyIndex" > 
  at <Home onAuthenticated=fn<setAuthenticatedUser> onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > > 
  at <RouterView onAuthenticated=fn<setAuthenticatedUser> > 
  at <App>
...
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'instantSearchInstance')
    at Proxy.eval (widget.js?c00b:1)
    at Proxy.created (widget.js?c00b:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:154)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:163)
    at callHook (runtime-core.esm-bundler.js?5c40:3177)
    at applyOptions (runtime-core.esm-bundler.js?5c40:3107)
    at finishComponentSetup (runtime-core.esm-bundler.js?5c40:7218)
    at setupStatefulComponent (runtime-core.esm-bundler.js?5c40:7143)
    at setupComponent (runtime-core.esm-bundler.js?5c40:7074)
    at mountComponent (runtime-core.esm-bundler.js?5c40:5079)

This is my main.js:

import { createApp } from 'vue'
import { fbAuth } from '@/firebase/config'

import App from '@/App.vue'
import router from '@/router'
import VTooltip from 'v-tooltip'
import 'v-tooltip/dist/v-tooltip.css'
import InstantSearch from 'vue-instantsearch/vue3/es'

let app

fbAuth.onAuthStateChanged(_user => {
    // Only mount the app to the DOM if the user is not authenticated
    // This means once authenticted a browser refresh doesn't result into having to login again
    if (!app) {
        app = createApp(App)

        // It's crucial to first define tooltip, before mounting the app
        app.use(VTooltip, {
            defaultDelay: {
                show: 500,
                hide: 500
            }
            // classes: 'bg-primary-blue-900 text-white'
        })
        app.use(InstantSearch)

        app.use(router).mount('#app')
    }
})

And this is a summary of my component:

<template>
  ...
  <ais-instant-search :search-client="searchClient" index-name="companyIndex">
    <ais-search-box />
    <ais-hits>
      <template v-slot:item="{ item }">
        <h2>{{ item.name }}</h2>
      </template>
    </ais-hits>
  </ais-instant-search>
  ...
</template>

<script>
import algoliasearch from 'algoliasearch/lite'
import { AisInstantSearch, AisSearchBox } from 'vue-instantsearch/vue3/es'
...
export default {
  name: 'Search',
  components: {
    AisInstantSearch,
    AisSearchBox,
    ...
  },
  props: [...],
  setup(props) {
    ...
    const searchClient = algoliasearch(
      '#######',
      '#######'
    )
    ...
    return {
      ...
      searchClient,
      ...
    }
  }
}
</script>

What can be wrong?

Haroenv commented 3 years ago

Hey @eugenevk, can you reproduce this in a sandbox? We have an example here which is fairly similar but isn't failing: https://codesandbox.io/s/github/algolia/doc-code-samples/tree/master/Vue%20InstantSearch/vue3-vue-cli

eugenevk commented 3 years ago

Pfew, that's not so easy @Haroenv. I have Firebase and Algolia integrated, so that's quite complicated to replicate quickly. Do you have another suggestion?

eugenevk commented 3 years ago

Hi @Haroenv, I have changed my search component as follows:

<template>
  <div class="container">
    <ais-instant-search
      :search-client="searchClient"
      index-name="companyIndex"
    >
    </ais-instant-search>
  </div>
</template>

<script>
import algoliasearch from 'algoliasearch'

export default {
  name: 'Search',
  setup() {
    const searchClient = algoliasearch(
      '######',
      '######'
    )

    return {
      searchClient
    }
  }
}
</script>
<style>
</style>

My main.js still looks the same:

import { createApp } from 'vue'
import { fbAuth } from '@/firebase/config'

import App from '@/App.vue'
import router from '@/router'
import VTooltip from 'v-tooltip'
import 'v-tooltip/dist/v-tooltip.css'
import InstantSearch from 'vue-instantsearch/vue3/es'

let app

fbAuth.onAuthStateChanged(_user => {
    // Only mount the app to the DOM if the user is not authenticated
    // This means once authenticted a browser refresh doesn't result into having to login again
    if (!app) {
        app = createApp(App)

        // It's crucial to first define tooltip, before mounting the app
        app.use(VTooltip, {
            defaultDelay: {
                show: 500,
                hide: 500
            }
            // classes: 'bg-primary-blue-900 text-white'
        })
        app.use(InstantSearch)

        app.use(router).mount('#app')
    }
})

I now get this error:

[HMR] Waiting for update signal from WDS...
algoliasearch.umd.js?60b7:2 POST https://#######-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20JavaScript%20(4.10.5)%3B%20Browser%3B%20instantsearch.js%20(4.30.2)%3B%20Vue%20(3.1.1)%3B%20Vue%20InstantSearch%20(4.0.1)%3B%20JS%20Helper%20(3.6.0) 404 (Not Found)
...
Uncaught (in promise) Error: Unhandled error. (undefined)
    at Proxy.emit (events.js?faa1:142)
    at AlgoliaSearchHelper.eval (InstantSearch.js?7c68:426)
    at AlgoliaSearchHelper.emit (events.js?faa1:153)
    at AlgoliaSearchHelper._dispatchAlgoliaError (algoliasearch.helper.js?ea40:1331)
...

When I use my own Application ID and search key in the sandbox, I do see proper results, so my index is working: image

eugenevk commented 3 years ago

Since I am using the Vue 3 Composition API, I changed the structure of the sandbox example to the Composition API, and then it still works in the sandbox. I changed the Githubissues.

  • Githubissues is a development platform for aggregating issues.