Ad

Flickity Not Initializing Properly When Data Comes From ReactiveVar

- 1 answer

I'm using flickity with Meteor and I'm trying to make a carousel from an array that comes from a ReactiveVar, like so:

Template.quickAnalyse.onRendered(function() {
    this.autorun(() =>{
        if (Template.instance().configuredSites.get() != undefined) {
            console.log(Date.now());
            $('.index-carousel').flickity({
                cellAlign: 'center',
                contain: true,
                setGallerySize: false,
                groupCells: true
            });
        }
    });
});

Template.quickAnalyse.helpers({
    getConfiguredSites() {
        console.log(Template.instance().configuredSites.get());
        console.log(Date.now());
        return Template.instance().configuredSites.get();
    },
});

The console.log(Date.now()) tells me that the getConfiguredSites() helper is running before the carousel initialization, so it should work.

The problem is that my carousel cells aren't rendered in theflickity-viewport.

It looks like this : https://postimg.cc/s1tF07mP

However, when I'm returning the datas like this :

Template.quickAnalyse.helpers({
    getConfiguredSites() {
        console.log(Template.instance().configuredSites.get());
        console.log(Date.now());
        return [{site: "1", installation: "1", batiment: "1"}, {site: "2", installation: "2", batiment: "2"}, {site: "3", installation: "3", batiment: "3"}]
    },
});

Here is the result : https://postimg.cc/vgZzzqCY

First I thought that the time between the helper and the initialization, int the first case, was to short but it's even shorter in the second case and it's working. So the problem probably comes from somewhere else but I can't figure it out.

The only thing that comes in my mind is that, maybe, the Template.instance().configuredSites.get() takes to long.

How could I solve that problem ?

Thanks.

EDIT: After testing my last theory, like that:

{{#each getConfiguredSites}}
    {{showTime}}
    <div class="carousel-cell">
        <div class="card index-card">
            <div class="card-body">
                <p>{{this.site}}</p>
                <p>{{this.installation}}</p>
                <p>{{this.batiment}}</p>
            </div>
        </div>
    </div>
{{/each}}

and

showTime() {
    console.log(Date.now());
}

The console.log(Date.now()) from the onRendered appears before the showTime's one... How could I solve that without adding an ugly setTimeout() in my onRendered ?

Thanks again.

Ad

Answer

I've managed to solve the problem.

Asking the question here made me ask myself some other questions and here is the final solution :

{{#with getConfiguredSites}}
    {{#each this}}
        <div class="carousel-cell col-xl-2">
            <div class="card index-card">
                <div class="card-body">
                    <p>{{this.site}}</p>
                    <p>{{this.installation}}</p>
                    <p>{{this.batiment}}</p>
                </div>
            </div>
        </div>
        {{#if isLast .. @index}}
            {{initializeCarousel}}
        {{/if}}
    {{/each}}
{{/with}}
Template.quickAnalyse.onRendered(function() {
    this.autorun(() => {
        if (Template.instance().readyForCarousel.get() === true) {
            $('.index-carousel').flickity({
                cellAlign: 'center',
                contain: true,
                setGallerySize: false,
                groupCells: true
            });
        }
    });
});

Template.quickAnalyse.helpers({
    getConfiguredSites() {
        return Template.instance().configuredSites.get();
    },

    isLast(data, index) {
        if (index + 1 == data.length)
            return true;
        return false;
    },

    initializeCarousel() {
        Template.instance().readyForCarousel.set(true);
    }
});

I hope it'll help someone else :)

Ad
source: stackoverflow.com
Ad