Go back Hotwire / Stimulus / Turbo ...

Send request from Stimulus controller


the proper way how to sent AJAX in Ruby on Rails Stimulus is via request.js lib: 


$ 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:

---------------------

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