1

I am trying to inject the filename JavaScript variable into my Ruby code like this:

"#{ajax_download_report_url(" + filename+ ")}"

It's a basic route URL but I need to pass this variable in HAML because I get it from this Ajax request:

:javascript
        var updaterId = setInterval(function() {
          $.ajax({
            url: #{admin_reports_url.to_json},
            dataType: "json",
            type:  "GET",
            data: {job_id: "#{job_id}"},
            success: function(response){
              var filename = response.file;
              switch(status) {
                case 'failed':
                  $('.loader').hide();
                  clearInterval(updaterId);
                  alert(message);
                  break;
                case 'completed':
                  $('.loader').hide();
                  clearInterval(updaterId);
                  location.href = "#{ajax_download_report_admin_reports_url(" + filename+ ")}";
                  break;
              }
            }
          })}, 1000);

Now I have an error:

ActionController::RoutingError - No route matches 
{:controller=>"admin/reports", :action=>"ajax_download_report", :file=>" + filename+ "}

which means that HAML can't properly evalute this code.

3
  • It doesn't look like you're trying to inject a JavaScript variable into Ruby code, which wouldn't work. Instead, it looks like you want to insert a Ruby variable into some JavaScript code. Commented Jun 27, 2013 at 5:33
  • @the Tin Man, var filename higher up. Commented Jun 27, 2013 at 5:35
  • Yes, those are Ruby strings being injected into JavaScript code via String interpolation inside #{...}. Commented Jun 27, 2013 at 6:12

4 Answers 4

1

This:

ajax_download_report_admin_reports_url(" + filename+ ")

is going to call a method in Ruby with a parameter of:

" + filename+ "

Which is why you see:

:file=>" + filename+ "

JavaScript is client-side running inside the browser, and can't touch the Ruby code on the server, so the JavaScript variable filename is invisible to Ruby and unreachable unless you send the value of filename back to the server somehow.


What I've done in the past, when I had a similar need, was to generate the URL and store it in a JavaScript variable definition, then use JavaScript string concatenation to insert the URL in the right place. Notice what this does:

File.dirname("http://foo.bar/baz/bor.html")
=> "http://foo.bar/baz"

It removes the resource name and leaves only the base URL. Using that:

:javascript
  var admin_reports_base_url = "#{ File.dirname(ajax_download_report_admin_reports_url('foo')) }/"
  var updaterId = setInterval(function() {
    $.ajax({
      url: #{admin_reports_url.to_json},
      dataType: "json",
      type:  "GET",
      data: {job_id: "#{job_id}"},
      success: function(response){
        var filename = response.file;
        switch(status) {
          case 'failed':
            $('.loader').hide();
            clearInterval(updaterId);
            alert(message);
            break;
          case 'completed':
            $('.loader').hide();
            clearInterval(updaterId);
            location.href = admin_reports_base_url + filename;
            break;
        }
      }
    })}, 1000);
Sign up to request clarification or add additional context in comments.

Comments

0
def get_url(x)
   return "a url: #{x}"
end

filename = 'abcd'

puts "#{get_url(filename)}"

--output:--
a url: abcd

But you are trying to use a js variable called filename, which does not exist until after the page is sent to the browser and after an ajax call is made some time later, in some ruby code that is executing now. No can do.

Comments

0

One solution would be to not use ruby code.

eg:

location.href = "admin/reports/ajax_download_report?file=" + filename;

3 Comments

Hard-coding it will work but negates the value of ajax_download_report_admin_reports_url().
You're right, but is there any other solution for his problem?
Yes. See the added part in my answer.
0
"#{ajax_download_report_admin_reports_url('')}" + filename

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.