Send request from Stimulus controller
$ bin/importmap pin @rails/request.js
// a/j/controllers/yeller_controller.js import { Controller } from "@hotwired/stimulus" import { post } from "@rails/request.js" export default class extends Controller { static values = { url: String } static targets = [ "form" ] async call() { const formData = new FormData(this.formTarget); const response = await post(this.urlValue, {responseKind: "turbo-stream", body: formData}) // if (response.ok) { // // ... // } } }
<div data-controller="yeller" data-yeller-url-value="/some/different/path"> <%= form_with url: entry_tags_url(entry), method: :post, html: {data: {yeller_target: "form"}} do |f| %> <%= text_field_tag :title, nil, data: { action: "keyup->yeller#call" } %> <%= f.submit "ok", class: "hidden" %> <% end %> </div>
alternative
import { Controller } from "@hotwired/stimulus" import { FetchRequest } from "@rails/request.js" # ... async load() { const formData = new FormData(this.formTarget); const request = new FetchRequest("post", this.urlValue, {responseKind: "turbo-stream", body: formData}) const response = await request.perform() // if (response.ok) { // // ... // } }
how does it work:
post("/my_endpoint", { body: {}, // Accepts Object, FormData or Files . contentType: "application/json", // optional, lib does some clever detection headers: {}, // optional - automatically adds X-CSRF-Token and Content-Type query: {}, // Accepts Object, FormData or URLSearchParams responseKind: "html" // Options are html, turbo-stream, json. })
surces:
- https://guides.rubyonrails.org/working_with_javascript_in_rails.html#replacements-for-rails-ujs-functionality
- https://github.com/rails/request.js
---------------------
Other solutions
Alternative solutions
inject link element within turbo frame tag and click it
import { Controller } from "@hotwired/stimulus" // stimulus controller that will inject a link into turbo_frame and click it // url is Stimulus Value + input field value // <div data-foobar-controller data-foobar export default class extends Controller { static values = { url: String } static targets = [ "input" ] load() { let url = this.urlValue + "?q=" + this.inputTarget.value let link = document.createElement("a") link.href = url this.element.appendChild(link).click() } }
Vanilla JS
saw a dude do it like this in here
sendRequest(url, formData) { console.log("Sending request to " + url); // fetch and trigger turbo_stream response fetch(url, { method: "POST", body: formData, headers: { "X-CSRF-Token": document.querySelector("meta[name='csrf-token']") .content, Accept: "text/vnd.turbo-stream.html", }, credentials: "same-origin", }).then((response) => { response.text().then((html) => { document.body.insertAdjacentHTML("beforeend", html); }); }); }
Rails UJS lib
still works but was replaced by requestjs