'How to connect alpinejs code and custom javascript file in rails

This Question might sound stupid. But i am learning alpine while implementing it with rails.

The problem is i am getting this error

alpine.js:1914 Uncaught ReferenceError: carouselData is not defined
    at eval (eval at d.el (alpine.js:144:14), <anonymous>:3:36)
    at d.el (alpine.js:144:14)
    at d (alpine.js:131:21)
    at f (alpine.js:139:12)
    at new be (alpine.js:1461:89)
    at Object.initializeComponent (alpine.js:1911:20)
    at alpine.js:1856:14
    at alpine.js:1870:9
    at NodeList.forEach (<anonymous>)
    at Object.discoverComponents (alpine.js:1869:15)

and my code is

testimonial_page.html.erb

<div class="mx-auto relative w-full" x-data="carouselData([{id: 1, text: 'first'}])">
  <!-- INNER CODE -->
</div>

app/javascript/packs/testimonial.js

function carouselData(slides) {
  return {
    slides,
    activeSlide: 1,
    goToPrevious() {
      this.activeSlide =
        this.activeSlide === 1 ? this.slides.length : this.activeSlide - 1;
    },
    goToNext() {
      this.activeSlide =
        this.activeSlide === this.slides.length ? 1 : this.activeSlide + 1;
    }
  };
}

console.log("hi testimonial file loaded")

I am getting hi testimonial file loaded in the console but still getting that error. I am so confused what's wrong ?

Although it is working fine if i put the script in same page Thank you in advance.



Solution 1:[1]

I think the problem is that you don't have a key for the slides object.

Change the carouselData function to

function carouselData(slides = null) {
  return {
    slides: slides,
    activeSlide: 1,
    goToPrevious() {
      this.activeSlide =
        this.activeSlide === 1 ? this.slides.length : this.activeSlide - 1;
    },
    goToNext() {
      this.activeSlide =
        this.activeSlide === this.slides.length ? 1 : this.activeSlide + 1;
    }
  };
}

Also you might consider assigning the slides inside x-init just in case, you don't have to though, especially I assume slides are rendered on the server first.

<div class="mx-auto relative w-full" 
  x-data="carouselData()"
  x-init="slides = [{id: 1, text: 'first'}]"
>
  <!-- INNER CODE -->
</div>

If you take that route, I'd do something like this as well:

<template x-if="slides.length">
  <!-- render slides -->
</template>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1