0

I am trying to make work Flickity Carousel by initing in blaze helpers. I do have following error:

Exception in template helper: TypeError: $(...).flickity is not a function

Here is my helper for the carousel template:

Template.carouselTemplate.onCreated(function bodyOnCreated() {
  this.state = new ReactiveDict();
  Meteor.subscribe('albums');
})

Template.carouselTemplate.helpers({
  albums() {
    return Albums.find({});
  },
  initializeCarousel () {
    $('.carousel').flickity({
      // options
      "lazyLoad": true
    });
  }
});

And the template itself:

<template name='carouselTemplate'>

<div class="carousel">

   {{#each albums}}
   <div class="carousel-cell">
     <img src={{cover}} alt="cat nose" />
   </div>
   {{/each}}
   {{initializeCarousel}}

</div>

<template />

P.S: I am open for other ways in order to make this work.

volna
  • 2,452
  • 4
  • 25
  • 61
  • 1
    please make sure you have added the js library for `flickity` on to your page correctly via ` – vijayP Aug 08 '16 at 12:47
  • @vijayP thank you for suggestion, I did recheked and they are in head tag. – volna Aug 08 '16 at 12:52
  • 1
    then please check the order of script tags. E.g. - JQuery should be first and then flickity.js. Please confirm that. – vijayP Aug 08 '16 at 12:54

1 Answers1

1

First make sure you're including the Flickity library using one of the following options:

1) Adding the proper JS reference to your application. For example:

/client/main.html

<head>
  <script src="https://npmcdn.com/flickity@2.0/dist/flickity.pkgd.min.js"></script>
</head>

OR

2) Embedding a copy of the Flickity library into your application. To do this you would store a copy of the flickity.pkgd.js file in your applications /client/compatibility directory (see the Special directories section of the Guide for more info).

OR

3) If using Meteor 1.3+, install the library using npm: meteor npm install --save flickity

Once the library is installed, instead of initializing your carousel through a Template helper, move your initialization code into a Template onRendered callback. Within that callback wrap your flickity initialization in a Tracker.autorun to make sure Albums results are loaded first. Something like:

Template.carouselTemplate.onCreated(function bodyOnCreated() {
  this.state = new ReactiveDict();
  Meteor.subscribe('albums');
});

Template.carouselTemplate.onRendered(function onRendered() {
  this.autorun(() => {
    if (Albums.find().count()) {
      $('.carousel').flickity();
    }
  });  
});

Template.carouselTemplate.helpers({
  albums() {
    return Albums.find({});
  }
});

Calling it through an onRendered callback means it will be called after the template is ready and inserted into the DOM (which is needed for jquery libraries that manipulate the DOM). You can then remove the initializeCarousel call from your Template.

hwillson
  • 1,399
  • 9
  • 7
  • thank you that did fixed the initialization. But there is still one issue I can't figure out is that carousel-cell divs are loaded outside of the the div slider. https://postimg.org/image/i4flwkq6j/ – volna Aug 08 '16 at 15:42
  • @AdrianSoleil I've updated my example to show you how to address this; you're initializing before the `Albums` results have been loaded. Using `autorun` in your `onRendered` callback will resolve this. – hwillson Aug 08 '16 at 16:44