Search code examples
jqueryruby-on-railsajaxviewcoffeescript

Rails - modify text of %p with dynamic variable


I have a basic form that, when submitted, triggers a Create request to an external API. On submit, a stage value with progress bar appears instead of the Submit button. The creation process takes time on the external API, so I had to run a couple of Show requests each second using while status == 'inactive' and stop when the Show request response has status: 'active'. Every Show request response also contains a 'stage' attribute which shows the stage of the creation process (Connecting, Creating, Fetching, Finishing etc.). With every request, the current stage is stored in the @stage variable, which can be accessed with ApiRequest.stage. Every API related stuff is in a service file.

My coffeescript that changes the Submit button with the stage+progress bar:

$('#new_connection').on 'submit', ->
    button = $('#submit_button')
    progress = $('.loading')
    button.fadeOut 500
    setTimeout (->
      if button.is(':hidden')
        progress.fadeIn 500
      return
    ), 509
    return

And the stage+progress bar partial:

.loading
  %p.center-align#stage <!-- This should display the stage in real time -->
  .progress <!-- This is a materializecss progress bar -->
    .indeterminate

How can I update the text inside #stage with ApiRequest.status every time the value changes in real-time staying on the same page, from the moment the form is submitted until the end (it will redirect to create.html when all the stuff in the background is done anyway)?


Solution

  • Ok so all you do is create a method in the controller that reads the variable: @stage = your method here.
    Write a respond_to do |format| with format.json { render json: { stage: @stage } }.
    Now you have to create a route for this custom controller method: get '/your/link', to: 'controller#custom_method', as: 'stage'.
    All that is left is to trigger this method through Ajax:

    $.get({
      url: "your/link.json",
      success: function(data) {
        $('#your_paragraph_id').text(data['stage]);
        },
    });
    

    You can put this Ajax call in a setInterval function.