4

So, I have a Rails application with webpacker, vue, turbolinks and stimulus js installed.
The problem that I am having is that even though the controller is only imported once and even if I temporarily disable turbolinks the initialize() funcition along with the connect() one get called twice.
This only happens if I do a refresh (i.e. not when I visit the page for the first time, but only if I perform a page reload).
Strangely enough the disconnect() is only getting called once (when I do leave the page)

This sucks because I need to modify the DOM in the initialize, so I get elements added twice. Does someone have any clue to what's causing this, and / or a solution?

EDIT: application.js as requested

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

import "stylesheets"
import "controllers"
import "components"

components/index.js

import Vue from 'vue/dist/vue.esm'
import BootstrapVue from 'bootstrap-vue'
import TurbolinksAdapter from 'vue-turbolinks'

Vue.use(BootstrapVue)
Vue.use(TurbolinksAdapter)

const components = {}
const context = require.context("components", true, /_component\.vue$/)
context.keys().forEach(filename => {
  const component_name = filename.replace(/^.*[\\\/]/, '').replace(/_component\.vue$/, '')
  const component = context(filename).default
  components[component_name] = component
})

document.addEventListener('turbolinks:load', () => {
  const app = new Vue({
    el: '#vueapp',
    mounted() {
      let input = document.querySelector('[autofocus]');
      if (input) {
        input.focus()
      }
    },
    components: { ...components }
  })
})

controllers/index.js

import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"

const application = Application.start()
const context = require.context("controllers", true, /_controller\.js$/)
application.load(definitionsFromContext(context))

in each and every file, if I console.log it gets logged only once...
only in the stimulus controller initialize or connect gets printed twice

this happens only when I reload the page, not when I first visit it.

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Anonymus
  • 175
  • 14
  • I am not sure why, but I think that vuejs is causing this. – Anonymus Mar 14 '21 at 21:08
  • You probably are calling them twice. Post application.js. – sam Mar 14 '21 at 21:51
  • I don't think so @sam, otherwise I would get the same result on a first page load. This happens only when I reload – Anonymus Mar 15 '21 at 11:01
  • Same issue here. I have a basic "hello" controller that logs "Hello, Stimulus". I have only one data-controller, it is triggered once at first page reload, then twice every time I reload. – pierre_loic Jun 24 '21 at 08:40

1 Answers1

6

This is probably due to Turbolinks. When navigating to a new page, Turbolinks first presents a cached version of the page (first stimulus connect) and afterwards replaces the body with the actual requested version of the page (second stimulus connect). See here for more details:

https://mrcodebot.com/turbolinks-calls-stimulus-connect-twice/

Chris
  • 1,008
  • 2
  • 11
  • 22