Episodes
candersson PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
This is excellent. I don't have a current use case for this but I just know it will come in handy at some point!

Another tool in the tool belt!

Thank you,

Chris


Tim Dowling PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
This is awesome, i'll be implementing this instead of the action text embeds so I have more control over the layout when displaying images and other documents. thank you!

Leonardo Barroeta PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Hello! Any recommendations for delete on storage on removedfile event?? Or there is other way to do it?

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
  Great question. Since the stimulus controller is creating a hidden element, you would need to remove that hidden element with something like this. I would console log the file to see what parameters are available and then remove the hidden element based on those parameters.

dropzone.on("removedfile", file => {
 
});

Tim Dowling PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
I do have a question, if i wanted to place this on an existing record  and remotely update on the record how would I go about handling the array of multiple files/images? I've tacked on the below to the "addedfile" method  but getting a 'unpermitted param evidences' error even though I have evidences: [] permitted in params. I think it's how i'm formatting the params in the formData.append - any clues? (I've got this working with one file)

let formData = new FormData()
            formData.append("event[evidences]", this.hiddenInput.value);
            Rails.ajax({
              url: this.data.get("update-url"),
              type: "PATCH",
              data: formData
              
            });

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
  Can you post an example of the parameters that are getting posted to the controller?

Also, do you have 

has_many_attached :evidences

In your event model?

Tim Dowling PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Thanks for the quick reply, It's actually coming through as Parameters: {"event"=>{"evidences"=>"event[evidences][]"}, "id"=>"22"} which tells me I may not need append, but removing this throws a 'event not present' error for the params.

Yup, I do have 

has_many_attached :evidences

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
When you drag the images on the page, did you verify that the direct upload is working? You should be able to check the console to see if Active Storage is creating the blobs. Once it creates the blob, the stimulus controller should create the hidden elements. Do an inspect on the browser to see what the elements look like. There does seem to be something off as the blob's signed_id should be getting set as the value.

Tim Dowling PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Thanks for pointing me in the right direction, it was working with the direct upload, but I was passing the blob signed id to the controller as a string rather than an array, this worked below:

 let formData = new FormData()
            formData.append("event[evidences][]", [this.hiddenInput.value] )
            Rails.ajax({
              url: this.data.get("update-url"),
              type: "PATCH",
              data: formData
              
            });

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
 I could not upload the file to Digital Ocean Spaces with this dropzone_controller. It was successful with other app with same credentials and via just a normal file_field.

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
  any error messages in either the JS Console or Rails console?

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
thank you so much for your prompt response! 

These are my errors.

  • Preflight response is not successful
  • XMLHttpRequest cannot load ... due to access control checks.
  • TypeError: undefined is not an object (evaluating 'blob.signed_id')



David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
It sounds like the direct upload did not work. See if anything is getting posted in the Rails console.


daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Thank you so much for your direction. Rails console is showing nothing wrong...

Started POST "/rails/active_storage/direct_uploads" for 127.0.0.1 at 2020-11-30 23:45:46 +0700
Processing by ActiveStorage::DirectUploadsController#create as JSON
  Parameters: {"blob"=>{"filename"=>"IMG_6766.JPG", "content_type"=>"image/jpeg", "byte_size"=>3809114, "checksum"=>"XXXXXXXXXXXXXXX"}, "direct_upload"=>{"blob"=>{"filename"=>"IMG_6766.JPG", "content_type"=>"image/jpeg", "byte_size"=>3809114, "checksum"=>"kJgGR4MU3XfpbzvoEZD83A=="}}}
   (18.0ms)  BEGIN
  ActiveStorage::Blob Create (21.2ms)  INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "byte_size", "checksum", "created_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["key", "XXXXXXXXXXXX"], ["filename", "IMG_6766.JPG"], ["content_type", "image/jpeg"], ["byte_size", 3809114], ["checksum", "kJgGR4MU3XfpbzvoEZD83A=="], ["created_at", "2020-11-30 16:45:46.410051"]]
   (2.9ms)  COMMIT
  S3 Storage (5.8ms) Generated URL for file at key: XXXXXXXXXX (https://XXXXXXXX.sfo2.digitaloceanspaces.com/x5e5iv60zg38xhzzbhitpxywvsfn?X-Amz-Algorithm=AWS4-HMAC-XXXXX&X-Amz-Credential=XXXXXXXXXXXXXX%2F20201130%2Fsfo2%2Fs3%2Faws4_request&X-Amz-Date=20201130T164546Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-length%3Bcontent-md5%3Bcontent-type%3Bhost&X-Amz-Signature=XXXXXXXXXXXXXXXXXXXX)
Completed 200 OK in 70ms (Views: 1.1ms | ActiveRecord: 42.1ms | Allocations: 5741)

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Ok, can you post the stimulus controller? It sounds like there is an issue with the data getting back from the direct upload. Can you also console log the blob that is getting returned from Direct Upload?

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
on XMLHttpRequest cannot load ...

<Error>
<Code>AccessDenied</Code>
<RequestId>tx00000000000007a28c110-005fc523ec-249a80a-sfo2a</RequestId>
<HostId>249a80a-sfo2a-sfo</HostId>
</Error>

on active storage.js...
 
this.callback('Error storing "' + this.file.name + '". Status: ' + this.xhr.status);

var blob = new BlobRecord(_this.file, checksum, _this.url);
          notify(_this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
          blob.create(function (error) {
            if (error) {
              callback(error);

dropzone_controller.js

import Dropzone from "dropzone";
import 'dropzone/dist/min/dropzone.min.css';
import 'dropzone/dist/min/basic.min.css';
import { DirectUpload } from "@rails/activestorage";

export default class extends ApplicationController {
static targets = ["input"]

connect() {
Dropzone.autoDiscover = false
this.inputTarget.disable = false
this.inputTarget.style.display = "none"
const dropzone = new Dropzone(this.element, {
url: '/',
maxFiles: '10',
maxFilesize: '10',
autoQueue: false
})

dropzone.on("addedfile", file => {
      setTimeout(() => {
        if (file.accepted) {
          const upload = new DirectUpload(file, this.url)
          upload.create((error, blob) => {
            this.hiddenInput = document.createElement("input")
            this.hiddenInput.type = "hidden"
            this.hiddenInput.name = this.inputTarget.name
            this.hiddenInput.value = blob.signed_id
            this.inputTarget.parentNode.insertBefore(this.hiddenInput, this.inputTarget.nextSibling)
            dropzone.emit("success", file)
            dropzone.emit("complete", file)
          })
        }
      }, 500)
    })
  }

  get url() {
    return this.inputTarget.getAttribute('data-direct-upload-url')
  }
}

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Can you console log the blob on upload.create?

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
I'm so sorry but how do you do that?

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
dropzone.on("addedfile", file => {
      setTimeout(() => {
        if (file.accepted) {
          const upload = new DirectUpload(file, this.url)
          upload.create((error, blob) => {
            ########## INSERT HERE #########
            console.log(blob)
            ########## INSERT HERE #########
            this.hiddenInput = document.createElement("input")
            this.hiddenInput.type = "hidden"
            this.hiddenInput.name = this.inputTarget.name
            this.hiddenInput.value = blob.signed_id
            this.inputTarget.parentNode.insertBefore(this.hiddenInput, this.inputTarget.nextSibling)
            dropzone.emit("success", file)
            dropzone.emit("complete", file)
          })
        }
      }, 500)
    })
  }

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
I'm so sorry that I am new subscriber of your channel and I don't know how to inspect the console.log(blob). 

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Sorry   for not being more clear, it is the Developer Tools Console within your browser.


daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
thank you for your kindness David. I am not sure if this is the correct answer but, the log just shows this:

"undefined" on console.log(blob)

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
[Log] undefined (admin-116a425f6e4133270456.js, line 289)

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Hi David! YES, I solved it!!

The issue was on DigitalOcean that it does not accept localhost:3000,
Response to preflight request doesn't pass access control check

This is how I solved.

1. create cors.xml
2. parse cors.xml to DigitalOcean Sapces through s3cmd by "s3cmd setcors cors.xml s3://{bucket_name}"

s3cmd installation:
https://www.digitalocean.com/docs/spaces/resources/s3cmd/

Your dropzone_controller.js code is the most simple and comprehensive, and it's a great starter compare to others in my opinion!

Thank you so much for your help David!  




David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Awesome   ! and thank you for posting your solution here for others to find! 

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Thank you for your kindly providing the direction too! 

Can I also request you for the StimulusJS and Datatable.net tutorial? 

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
I like the idea. Datatables is pretty powerful and crazy complicated when doing something beyond a simple table.

daijinara PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Thank you for your consideration :)

I figured out my datatable_controller.js as below. I hope it is useful to the community members here :D

import DataTable from "datatables.net";
require('datatables.net-bs4');
require('datatables.net-buttons');
require('datatables.net-buttons-bs4');
require('datatables.net-select');

export default class extends ApplicationController {
	static targets = ["table"]

	initialize() {

		const options = {
			keys: !0,
			select: {
				style: "multi"
			},
			language: {
				paginate: {
					previous: "<i class='fas fa-angle-left'>",
					next: "<i class='fas fa-angle-right'>"
				}
			},
		};

		// Init the datatable
		const table = $('#datatable-basic').on( 'init.dt', function () {
			$('div.dataTables_length select').removeClass('custom-select custom-select-sm');
	  }).DataTable(options);
  }

}

David Kimura PRO said almost 2 years ago on StimulusJS, Active Storage and DropzoneJS :
Cool. I'll probably still cover it without the jquery portion and also bring in async loading of the data. 😀

AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Hi David,
Thanks for your videos 😀

While I'm trying your example, I got an error:
Uncaught TypeError: Cannot read property 'signed_id' of undefined

Console errors...

Network error shows it AJAX call issues...


And here is what triggered the issue.
And here how dropzone area looks like.


Any idea what could cause such error?
Thanks...

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
The blob that comes back looks like it's not set. Did ActiveStorage store it? (check the Rails logs) 

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
When it made the post to your direct upload endpoint, it errored out with a 422. The Rails logs may help. Have you tried testing direct upload without any stimulus or anything else? You may have another underlying issue. 

AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Here is rails log on upload an image attempt  

10:34:19 web.1     | Started POST "/rails/active_storage/direct_uploads" for ::1 at 2021-03-27 10:34:19 +0400
10:34:20 web.1     | Processing by ActiveStorage::DirectUploadsController#create as JSON
10:34:20 web.1     |   Parameters: {"blob"=>{"filename"=>"Screen Shot 2021-03-26 at 21.24.18 (2).png", "content_type"=>"image/png", "byte_size"=>2957763, "checksum"=>"knBZupa2TdcuU831UUgj+A=="}, "direct_upload"=>{"blob"=>{"filename"=>"Screen Shot 2021-03-26 at 21.24.18 (2).png", "content_type"=>"image/png", "byte_size"=>2957763, "checksum"=>"knBZupa2TdcuU831UUgj+A=="}}}
10:34:20 web.1     | Can't verify CSRF token authenticity.
10:34:20 web.1     | Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms | Allocations: 1024)
10:34:20 web.1     |
10:34:20 web.1     |
10:34:20 web.1     |
10:34:20 web.1     | ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
10:34:20 web.1     |


David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Can't verify CSRF token authenticity.

This does seem to be the issue. What does the form and stimulus controller look like? 

AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
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))

dropzone_controller.js
import { Controller } from "stimulus";
import Dropzone from "dropzone";
import "dropzone/dist/min/dropzone.min.css";
import "dropzone/dist/min/basic.min.css";
import { DirectUpload } from "@rails/activestorage";

export default class extends Controller {    
  static targets = ["input"];
    connect() {
        Dropzone.autoDisc  = false;
        this.inputTarget.disable = true;
        this.inputTarget.style.display = "none";
        const dropzone = new Dropzone(this.element, {
            url: "/",
            maxFiles: "10",
            maxFilesize: "10",
            autoQueue: false,
        });
        dropzone.on("addedfile", (file) => {
            setTimeout(() => {
                if (file.accepted) {
                    const upload = new DirectUpload(file, this.url);
                    upload.create((error, blob) => {
                        this.hiddenInput = document.createElement("input");
                        this.hiddenInput.type = "hidden";
                        this.hiddenInput.name = this.inputTarget.name;
                        this.hiddenInput.value = blob.signed_id;
                        this.inputTarget.parentNode.insertBefore(
                            this.hiddenInput,
                            this.inputTarget.nextSibling
                        );
                        dropzone.emit("success", file);
                        dropzone.emit("complete", file);
                    });
                }
            }, 500);
        });
    }
    get url() {
        return this.inputTarget.getAttribute("data-direct-upload-url");
    }}

= form_with(model: guest, multipart: true, local: true, id:"new_gues") do |form|

avatar file field in form.html.haml
.dropzone.dropzone-default.dz-clickable{"data-controller" => "dropzone", "data-dropzone-max-file-size" => "2", "data-dropzone-max-files" => "1"}          
  = form.file_field :avatar, direct_upload: true, class: 'form-input py-10', accept: 'image/png, image/jpeg, image/gif, image/tiff', size_limit: 2_000_000, data: { target: 'dropzone.input' }          
  .text-gray-600.dropzone-msg.dz-message.needsclick         
    %h3.text-base.font-bold.dropzone-msg-title Drag or click to upload your Company logo
      %span.text-xs.dropzone-msg-desc 
        Choose a square image with a solid background colour of at least 100x100px.
      - if @guest.avatar.attached?              
        = image_tag(@guest.avatar, class: "rounded-full h-20 w-20 mx-auto mt-2")

The strange thing is, I this app was working fine for weeks, and after switched from ERB to HAML, that happened.
Also, I have User model by devise, where uploading avatar works very well as you expect it, where I don't use dropdown JS or any JavaScript library!!!

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Try changing the user avatar file field to a direct upload and see if you get the same issue.
If you revert back to ERB, do you get the same issue?

AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
I tried using ERB but no luck.
How would I use direct upload instead of file_field?

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
I just pulled down the source for this episode and tried things out. It worked (once I updated an unrelated issue sass-rails). What ActiveStorage storage mechanism are you using?


AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
I'm still in development stage, so I'm using local. Haven't user other services yet.

AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Here is the response from Network tab inside Firefox Dev Tools.

ActionController::InvalidAuthenticityToken at /rails/active_storage/direct_uploads
==================================================================================

ActionController::InvalidAuthenticityToken

> To access an interactive console with this error, point your browser to: /__better_errors


actionpack (6.1.3) lib/action_controller/metal/request_forgery_protection.rb, line 211
--------------------------------------------------------------------------------------

``` ruby
  206           def initialize(controller)
  207             @controller = controller
  208           end
  209   
  210           def handle_unverified_request
> 211             raise ActionController::InvalidAuthenticityToken
  212           end
  213         end
  214       end
  215   
  216       private
```

App backtrace
-------------



Full backtrace
--------------

 - actionpack (6.1.3) lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request'
 - actionpack (6.1.3) lib/action_controller/metal/request_forgery_protection.rb:243:in `handle_unverified_request'
 - devise (4.7.3) lib/devise/controllers/helpers.rb:255:in `handle_unverified_request'
 - actionpack (6.1.3) lib/action_controller/metal/request_forgery_protection.rb:238:in `verify_authenticity_token'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:427:in `block in make_lambda'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'
 - actionpack (6.1.3) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:199:in `block in halting'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:512:in `block in invoke_before'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:512:in `invoke_before'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:115:in `block in run_callbacks'
 - actiontext (6.1.3) lib/action_text/rendering.rb:20:in `with_renderer'
 - actiontext (6.1.3) lib/action_text/engine.rb:55:in `block (4 levels) in <class:Engine>'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:126:in `block in run_callbacks'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:137:in `run_callbacks'
 - actionpack (6.1.3) lib/abstract_controller/callbacks.rb:41:in `process_action'
 - actionpack (6.1.3) lib/action_controller/metal/rescue.rb:22:in `process_action'
 - actionpack (6.1.3) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
 - activesupport (6.1.3) lib/active_support/notifications.rb:203:in `block in instrument'
 - activesupport (6.1.3) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
 - activesupport (6.1.3) lib/active_support/notifications.rb:203:in `instrument'
 - actionpack (6.1.3) lib/action_controller/metal/instrumentation.rb:33:in `process_action'
 - actionpack (6.1.3) lib/action_controller/metal/params_wrapper.rb:249:in `process_action'
 - activerecord (6.1.3) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
 - actionpack (6.1.3) lib/abstract_controller/base.rb:165:in `process'
 - actionview (6.1.3) lib/action_view/rendering.rb:39:in `process'
 - actionpack (6.1.3) lib/action_controller/metal.rb:190:in `dispatch'
 - actionpack (6.1.3) lib/action_controller/metal.rb:254:in `dispatch'
 - actionpack (6.1.3) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
 - actionpack (6.1.3) lib/action_dispatch/routing/route_set.rb:33:in `serve'
 - actionpack (6.1.3) lib/action_dispatch/journey/router.rb:50:in `block in serve'
 - actionpack (6.1.3) lib/action_dispatch/journey/router.rb:32:in `serve'
 - actionpack (6.1.3) lib/action_dispatch/routing/route_set.rb:842:in `call'
 - warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
 - warden (1.2.9) lib/warden/manager.rb:34:in `call'
 - rack (2.2.3) lib/rack/tempfile_reaper.rb:15:in `call'
 - rack (2.2.3) lib/rack/etag.rb:27:in `call'
 - rack (2.2.3) lib/rack/conditional_get.rb:40:in `call'
 - rack (2.2.3) lib/rack/head.rb:12:in `call'
 - actionpack (6.1.3) lib/action_dispatch/http/permissions_policy.rb:22:in `call'
 - actionpack (6.1.3) lib/action_dispatch/http/content_security_policy.rb:18:in `call'
 - rack (2.2.3) lib/rack/session/abstract/id.rb:266:in `context'
 - rack (2.2.3) lib/rack/session/abstract/id.rb:260:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/cookies.rb:689:in `call'
 - activerecord (6.1.3) lib/active_record/migration.rb:601:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
 - activesupport (6.1.3) lib/active_support/callbacks.rb:98:in `run_callbacks'
 - actionpack (6.1.3) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
 - better_errors (2.9.1) lib/better_errors/middleware.rb:87:in `protected_app_call'
 - better_errors (2.9.1) lib/better_errors/middleware.rb:82:in `better_errors_call'
 - better_errors (2.9.1) lib/better_errors/middleware.rb:60:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/debug_exceptions.rb:29:in `call'
 - web-console (4.1.0) lib/web_console/middleware.rb:132:in `call_app'
 - web-console (4.1.0) lib/web_console/middleware.rb:28:in `block in call'
 - web-console (4.1.0) lib/web_console/middleware.rb:17:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
 - railties (6.1.3) lib/rails/rack/logger.rb:37:in `call_app'
 - railties (6.1.3) lib/rails/rack/logger.rb:26:in `block in call'
 - activesupport (6.1.3) lib/active_support/tagged_logging.rb:99:in `block in tagged'
 - activesupport (6.1.3) lib/active_support/tagged_logging.rb:37:in `tagged'
 - activesupport (6.1.3) lib/active_support/tagged_logging.rb:99:in `tagged'
 - railties (6.1.3) lib/rails/rack/logger.rb:26:in `call'
 - sprockets-rails (3.2.2) lib/sprockets/rails/quiet_assets.rb:13:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/request_id.rb:26:in `call'
 - rack (2.2.3) lib/rack/method_override.rb:24:in `call'
 - rack (2.2.3) lib/rack/runtime.rb:22:in `call'
 - activesupport (6.1.3) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/executor.rb:14:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/static.rb:24:in `call'
 - rack (2.2.3) lib/rack/sendfile.rb:110:in `call'
 - actionpack (6.1.3) lib/action_dispatch/middleware/host_authorization.rb:98:in `call'
 - webpacker (5.2.1) lib/webpacker/dev_server_proxy.rb:25:in `perform_request'
 - rack-proxy (0.6.5) lib/rack/proxy.rb:57:in `call'
 - railties (6.1.3) lib/rails/engine.rb:539:in `call'
 - puma (5.2.2) lib/puma/configuration.rb:248:in `call'
 - puma (5.2.2) lib/puma/request.rb:76:in `block in handle_request'
 - puma (5.2.2) lib/puma/thread_pool.rb:337:in `with_force_shutdown'
 - puma (5.2.2) lib/puma/request.rb:75:in `handle_request'
 - puma (5.2.2) lib/puma/server.rb:431:in `process_client'
 - puma (5.2.2) lib/puma/thread_pool.rb:145:in `block in spawn_thread'



AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
After days for searching, trying new solution and new code asking on SO, I decided to start fresh 🙁

It is hard since I have been working on this project for weeks. But nothing I can do. Maybe, a fresh start is a good way to inspect code again and think of new way to design and implement features.

Thanks for your help David 😀 👍🏼

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  By chance, are you overriding ActiveStorage::DirectUploadsController#create? I've pulled your view code and stimulus controller code into the project, updated to Rails 6.1.3.1, updated yarn packages (active storage, ujs and dropzone). It still works locally.

AhmedNadar PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  No I haven't override ActiveStorage::DirectUploadsController#create. I don't know what cause this issue.
I have created a mini/test app with Rails 6.1.3.1, stimulus, active storage, dropzone, ujs and it works fine. I tried different dropzone_controller.js code, and no issues.
Then I tried to replicate my original app, using one model that relay on heavily on dropzone and it works fine.🤷🏻‍♂️

I would guess HAML caused some issues, because switching from ERB to HAML was the only major change I've made across the app. It was working fine for 4 weeks. 
Lesson learned, never do a major switch after long development time.

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  Personally, I'm not a fan of Less/HAML, but one thing that you could try doing is to inspect the rendered HTML from both scenarios to see if there is any difference. There could be one little change that is causing the whole smash to do something strange.

atstockland said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Hi David and friends - 

resizeHeight and resizeQuality don't seem to be affecting the uploaded image in any way.  I'm wondering if maybe it has something to do with direct_upload...maybe those options are never triggered.  Did you play with these settings when using DropzoneJS?

My Dropzone_controller looks like this:
import { Controller } from "stimulus"
import Dropzone from "dropzone"
import 'dropzone/dist/min/dropzone.min.css'
import 'dropzone/dist/min/basic.min.css'
import { DirectUpload } from "@rails/activestorage"

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

  connect() {
    Dropzone.autoDiscover = false

    this.inputTarget.disable = true
    this.inputTarget.style.display = "none"
    const dropzone = new Dropzone(this.element, {
      url: '/',
      maxFiles: 10,
      maxFilesize: 6,
      addRemoveLinks: true,
      resizeHeight: 50,
      resizeQuality: 0.1,
      autoQueue: false
    })

    dropzone.on("addedfile", file => {
      setTimeout(() => {
        if (file.accepted) {
          const upload = new DirectUpload(file, this.url)
          upload.create((error, blob) => {
            this.hiddenInput = document.createElement("input")
            this.hiddenInput.type = "hidden"
            this.hiddenInput.name = this.inputTarget.name
            this.hiddenInput.value = blob.signed_id
            this.inputTarget.parentNode.insertBefore(this.hiddenInput, this.inputTarget.nextSibling)
            dropzone.emit("success", file)
            dropzone.emit("complete", file)
          })
        }
      }, 500)
    })
  }

  get url() {
    return this.inputTarget.getAttribute('data-direct-upload-url')
  }
}

So, if I attach a 1 megabyte 800x800 image...I'm expecting to get back a 50px image that looks pretty bad (due to resizeQuality 0.1).  However, I get back the same image I originally attached.  No compression or size changes at all.

Also, I'm curious if you know...by default will DropzoneJS upsize?  Or, is it smart enough to not upsize?  Also, is it smart enough to skip resize options for non-images?  The docs don't specify.

Perhaps this is better suited for StackOverflow.

Thanks!!!!

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  I haven't messed around with those options to know if they are making any difference or not. You could always make a custom upload controller, use the new url instead of "this.url" which is taken from the direct upload, and return a variant record. However, you'd still have the full size image stored via ActiveStorage and may need to clean those up periodically.

Jamie Crone PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
This is great! I do have an issue in production. I think it might be where I ran  yarn add dropzone. I am using an Ubuntu server on DigitalOcean. My dev environment is all Ubuntu. I ran yarn add dropzone in my root directory for the app, installed but same result as below. Then I ran it in my root directory and had the same result below. Then I tried to run it in my myapp/current directory. Maybe its something else. Just looking for some ideas to try

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  Can you post the relevant bits of the stimulus controller, any console errors in the browser? Typically, it would error out in the assets compilation if there is a missing asset or something that you're referencing.

Jamie Crone PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  Thanks for replying! I do have 3 errors pop up on the console, first one being 
Access to XMLHttpRequest at 'https://uatmyskiswap.sfo3.digitaloceanspaces.com/mtn1067cgyun59enm7tg5pepje…Signature=9a216bd…' 
from origin 'http://uat.myskiswap.com' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' 
header is present on the requested resource.

Maybe this is the issue or a separate one. The second one is
dropzone_controller.js:29 Uncaught TypeError: Cannot read property 'signed_id' of undefined
    at dropzone_controller.js:29
    at e.callback (activestorage.js:879)
    at e.value (activestorage.js:841)
    at XMLHttpRequest.<anonymous> (activestorage.js:815)

The error above comes from the this.hiddenInput.value = blob.signed_id  below
    dropzone.on("addedfile", file => {
      setTimeout(() => {
        if (file.accepted) {
          const upload = new DirectUpload(file, this.url)
          upload.create((error, blob) => {
            this.hiddenInput = document.createElement("input")
            this.hiddenInput.type = "hidden"
            this.hiddenInput.name = this.inputTarget.name
            this.hiddenInput.value = blob.signed_id 
            this.inputTarget.parentNode.insertBefore(this.hiddenInput, this.inputTarget.nextSibling)
            dropzone.emit("success", file)
            dropzone.emit("complete", file)
          })
        }
      }, 500)


The last error is because the of the error above which just doesn't create 
activestorage.js:823 
PUT https://uatmyskiswap.sfo3.digitaloceanspaces.com/mtn1067cgyun59enm7tg5pepje…Signature=9a216bd… 
net::ERR_FAILED

When I don't use dropzone I don't have this issue uploading files or avatars 

David Kimura PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
   This is a CORS issue likely due to the JS doing a “direct upload”. In order to fix this, you will need to change the digital ocean spaces CORS settings. You would likely have this same problem if you were using active storage direct uploads without drop zone.

Jamie Crone PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
  Thanks! The CORS solved the issue of it uploading, but the animation upload still is not working. Works in dev but not once I upload it, not really sure why maybe i am missing a library in staging? Ill keep messing around see if I can figure it out. If you have any suggestions let me know. No console errors either

Here is the staging site



Here is dev environment

Jamie Crone PRO said over 1 year ago on StimulusJS, Active Storage and DropzoneJS :
Figured out my issue, I was using Tailwind CSS and it was purging the unused style sheets and for some reason dropzone was added to that

marklar said 11 months ago on StimulusJS, Active Storage and DropzoneJS :
  did you end up getting resize working? If yes, are you able to share how? Thanks.

colleen said 11 months ago on StimulusJS, Active Storage and DropzoneJS :
  -> The resizeWidth dropzone option doesn't work b/c the autoqueue:false bypasses the calling of transformFile in the dropzone source. Trying to figure out right now where to call transformFile. There are also several "solutions" on SO. 

marklar said 11 months ago on StimulusJS, Active Storage and DropzoneJS :
  I wasn't aware that  autoqueue:false bypasses the calling of transformFile. Thanks for pointing that out. Did you end up figuring out a way to call transformFile?

colleen said 11 months ago on StimulusJS, Active Storage and DropzoneJS :
  Nope, unfortunately not. I tried to hook into it and call it from my Stimulus controller, but of course the `this` scope got all screwed up. Let me know if you use it! I'm looking to use another library or do it manually. 

stephen.schuez PRO said 6 months ago on StimulusJS, Active Storage and DropzoneJS :
  Thanks for the great video and the simple setup! I've been banging my head against trying to display the photos that are already stored, when I open my form. I did something like this:
JSON.parse(this.filesTarget.dataset.urls).forEach((image) => {
  let mockFile = { name: `${image.name}`, size: 12345 };
  dropzone.displayExistingFile(mockFile, image.url);
})
The dataset gives me the external url (in this case on cloudinary), but I can't seem to use the displayExistingFile method w external urls... How would you go about displaying exising images in DZ?

P.S.
Maybe for a follow-up screencast: How to delete them again from the db?
And maybe as a bonus: Make them sortablejs?

Login to Comment