ruby-on-railsrubystimulusjs

Trying to create a preview with stimulus doesn't work in Rails


I am trying to add a preview when uploading an image, and I've came across this tutorial: "Image Previews with Active Storage in Ruby on Rails 7"

I followed every step but I realized that the stimulus connect function is never called. I don't have any errors in the console, it just doesn't work. I've tried reinstalling the stimulus but it didn't worked.

HTML View

<div data-controller = "previews">
<%= form.file_field :image, direct_upload: true, data: { previews_target: "input", action: "change->previews#preview"}, class:"form-control" %>

<% if movie.image.attached? %>
    <%= image_tag movie.image, data: { previews_target: "preview"}, class: "image-cover-preview" %>
<% else %>
    <%= image_tag "", data: { previews_target: "preview"}, class: "image-cover-preview" %>
<% end %>

previews_controller.js

import { Controller } from "@hotwired/stimulus"


export default class extends Controller 
{
  static targets = ["input", "preview"];

  connect() 
  {
    console.log("THIS IS A PREVIEW", this.element);
  }

  preview()
  {
    let input = this.inputTarget;
    let preview = this.previewTarget;
    let file = input.files[0];
    let reader = new FileReader();
reader.onloadend = function()
{
  preview.src = reader.result;
};

if(file)
{
  reader.readAsDataURL(file);
}
else
{
  preview.src = "";
}
  }
}

importmap.rb

# Pin npm packages by running ./bin/importmap

pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"

application.html.erb

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
    <%= render 'home/header' %>

  </head>
  <body>
    <%= stylesheet_link_tag "application" %>
    <br>
    <%= render 'layouts/alerts'%>
    <% if notice %>
    <% end %>
    <br>

    <%= yield %>

  </body>
</html>
</html>

application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"

Solution

  • Just modify the file app/views/application.html.erb

    <!doctype html>
    <html lang="en">
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
    
       <%= javascript_importmap_tags %> <!-- missing line -->
       <%= render 'home/header' %>
    
      </head>
    

    This will load all js libraries specified in config/importmap.rb