0

In my Rails-Stimulus controller, I fetch data in a loop from a function in which I've setTimeout. How do I set the target value from within the setTimeout?

My form partial

<%= text_field_tag :first_date, "Select Date One", data: {controller: 'flatpickr'} %>
<div data-controller="hist">
    <div data-hist-target="one"></div>
    <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 border border-blue-700 rounded"
        data-action='hist#get_history'>
        Hist
    </button>
</div>

My controller

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [ "one" ]
  
  connect() {
    
  }

  get_date_history(aDate) {
    setTimeout(function() {
      var history = new Array()
      let month   = aDate.slice(5,7)
      let date    = aDate.slice(8,10)
      let url     = 'http://numbersapi.com/' + month + '/' + date + '/date'

      for (let step = 0; step < 5; step++) {
        fetch(url)
          .then(response => response.text())
          .then(function(data)  {
            history.push(data)
          })
          .catch(err => console.log('Request Failed', err)) // Catch errors
      }
      // can we set oneTarget value here? how?
    }, 2500)
  }

  get_history() {
    var date = document.getElementById("first_date").value
    this.get_date_history(date)
  }
}
user1575148
  • 561
  • 6
  • 28
  • Does this answer your question? [How to access a Stimulus JS controller method from inside a nested function?](https://stackoverflow.com/questions/70969944/how-to-access-a-stimulus-js-controller-method-from-inside-a-nested-function) – LB Ben Johnston Apr 30 '22 at 03:42
  • Does this answer your question? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – ggorlen May 28 '22 at 21:44
  • Seems like you want `Promise.all` so you can get the results of all of the `fetch` calls, then set `this.oneTarget`. You can use an arrow function or manually bind `this` to the `setTimeout` callback so that `this` will refer to the controller. – ggorlen May 28 '22 at 21:45

0 Answers0