9

I have the following code in one of my views:

<button type="button" onclick="analyze();">Analyze</button>

And, the .js.coffee file for the corresponding controller contains

analyze = ->

  $.ajax
    type: "GET"
    url: "http://localhost:3000/api/logs"
    success: (data) ->
      Analytics.doAnalysis data
      return;

  return;

But, when I click the button, I get an error in console saying Uncaught ReferenceError: analyze is not defined. I think my onclick is not correctly defined. What is the recommended way of doing this?

2 Answers 2

20

I am new to web development

Since you're new, let me give you some ideas on how to improve your code:


Unobtrusive JS (UJS)

This tutorial explains it very well

Rails convention is geared towards "unobtrusive" javascript functionality. This means you can assign events to elements on your page without having to reference those elements directly (don't use inline onclick etc)

This is best described in the same way as CSS - using inline CSS is ridiculously laborious & seen as bad practice (it's not DRY). A much better way is to have a central stylesheet, which you can then use to style elements on the page.

Unobtrusive Javascript works in the same way - keep everything in files you call at runtime:

#app/assets/javascripts/application.js
$(".element").on("click", function(){
    ...
});

The importance of this cannot be stated enough - having unobtrusive JS is one of the best programming patterns you can apply; it not only DRIES up your code, but also ensures future development can be kept modular (a gold standard in development)


Ajax

Since you're using ajax, you may wish to use the Rails UJS Ajax functionality, which basically means this:

<%= button_to "Analyze", analytics_api_path, id: "analyze", remote: true %>

The remote: true option of this calls the Rails UJS driver's ajax functionality - basically setting up an ajax call without you having to write any code. The caveats of this are that you need to handle your own ajax:success process, and you'll need to point the element to the correct href

I would do this:

#app/assets/javascripts/application.js.coffee
$("#analyze").on "ajax:success", (data, status, xhr) ->
    Analytics.doAnalysis data
Sign up to request clarification or add additional context in comments.

Comments

11

Change this:

analyze = ->

To this:

window.analyze = ->

Functions in coffeescript are not global by default.

2 Comments

Thanks very much :) I am new to web development and had one more. Is there any way to access the function without making it global? What is the best practice?
"best" practice is debatable, but you might read up on "unobtrusive" javascript. In a perfect world, instead of your HTML pointing to Javascript functions, your javascript injects itself into the HTML. See: guides.rubyonrails.org/…

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.