typesense / typesense-instantsearch-adapter

A JS adapter library to build rich search interfaces with Typesense and InstantSearch.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't update component value in the adapater

guillaumetch opened this issue · comments

Description

Hi, I currently facing an issue using the adapter with VueJs.
I have a vue slider component (https://www.npmjs.com/package/vue-slider-component) and others in my Vue.
I need to update to value of vue slider component after mounted to trigger a search but I can't the component in the mounted() method

Steps to reproduce

Here is my code

export default {
    data() {
        return {
            searchClient: null,
            routing,
            filterIcon: '/sgdm-theme/images/filter.png',
            moneyFormatter: v => "${( v + '€')}",
            favorites: [],
            limit: 10,
            showMoreLimit: 1000,
            paddingPagination: this.isMobile ? 1 : 2,
            isMobile: isMobileOnly ? 1 : 0,
            isTablet: isTablet ? 1 : 0
        };
    },
    components: {
        VueSlider,
        Collapsible,
        MoneyFormat,
        isMobileOnly,
        isTablet
    },
    props: [
        'dataPath',
        'typesenseUrl',
        'typesenseKey',
        'typesenseVehicles',
        'urlAideEtConseils',
        'urlGaranties',
        'urlWishListAdd',
        'urlWishListRemove',
        'urlWishList',
        'dataUser',
        'urlLogin',
        'urlRegister',
        'infoPrice',
        'rangeMin',
        'rangeMax'
    ],
    methods: {
        pageChange() {
            document.body.scrollIntoView();
        },
        showAlert() {
            this.$swal('Vous devez être <a href="'+this.urlLogin+'">connecté</a> ou <a href="'+this.urlRegister+'">créer un compte</a> pour utiliser les favoris !');
        },

        generateThumbnail(item)
        {
            var path = item.image;
            if(this.isMobile)
            {
                var path = item.image_mobile;
            }

            return path;
        },

        generatePlacehold()
        {
            var path = 'https://via.placeholder.com/248x164/CCCCCC/CCCCCC';
            if(this.isMobile)
            {
                var path = 'https://via.placeholder.com/320x190/CCCCCC/CCCCCC';
            }

            return path;
        },

        toValue(value, range) {
            return [
                typeof value.min === "number" ? value.min : range.min,
                typeof value.max === "number" ? value.max : range.max,
            ];
        },

        removeEmpty(items) {
            return items.filter(item => item.label.length > 0)
        },

        isFavorit(itemId)
        {
            return this.favorites.includes(itemId);
        },

        getFavorites()
        {
            axios.get(Routing.generate('ajax_whishlist'))
                .then(response => {
                    this.favorites = JSON.parse(response.data);

                    return this.favorites;
                });
        },

        isLimitPrice(price)
        {
            return parseInt(price) >= limitPrice ? 1 : 0;
        }

    },
    mounted: function () {

        const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
            server: {
                apiKey: this.typesenseKey,
                nodes: [
                    {
                        url: this.typesenseUrl
                    },
                ],
            },
            cacheSearchResultsForSeconds: 0,

            additionalSearchParameters: {
                query_by: "label,brand,short_description,motor,version,category",
                sort_by: "random_sort_field:desc",
                filter_by: "monthly_rent:>0",
                use_cache: false
            },
        });

        this.$data.searchClient = typesenseInstantsearchAdapter.searchClient;

        this.getFavorites();

        new Tooltip(document.body, {
            selector: "[data-bs-toggle='tooltip']",
        })
       

        // Access the VueSlider component using the $refs object
        const slider = this.$refs.slider;
        console.log(this.$refs);


        // Set the value of the slider programmatically
        slider.setValue([this.rangeMin, this.rangeMax]);
    }
};

Expected Behavior

Update the vue slider component value to trigger the search

Actual Behavior

In the mounted() method, I try to access my component but I got
2023-05-03_10-25

My Vue slider component code

<h4>Prix</h4>
<h5>par mois TTC</h5>
<ais-range-input attribute="monthly_rent">
    <template v-slot="{ currentRefinement, range, refine }">
        <vue-slider
            :min="range.min"
            :max="range.max"
            :lazy="true"
            :value=[rangeMin,rangeMax]
            @change="refine({ min: $event[0], max: $event[1] })"
            :tooltip-formatter="moneyFormatter"
            ref="slider"
        />
    </template>
</ais-range-input>

Metadata

Typesense Version:

0.23.1

OS:
Ubuntu 22.04.1 LTS 64 bit

hi,
i need the same thing, i want to initialise on dom ready the slider with 2 variables come from a form homepage.
so client use slider, click on submit form, i need to use min and max on the search page with these variables already set.
how to do that with the adapter and vue-slider-component ?

@jasonbosco hello, can we have a hint for this issue please ?

@guillaumetch Your question is technically unrelated to how typesense-instantsearch-adapter functions and more of a Vue question. While I'm familiar with Vue (definitely not an expert), I'm not sure why the standard Vue ref mechanism is not working to access that nested slider component... Could you try posting on Stackoverflow - there should be more Vue experts there.

@ibasaw I just stumbled on this thread, may be this helps: algolia/vue-instantsearch#717 (comment)