Skip to main content

Refactoring Your jQuery Code with Objects in Coffeescript Discussion

General • Asked by Chris Oliver

Thanks for this episode! I was recently working on a Rails project and saw much the same setup in their JS, didn't really grasp it at a high level. I could see it was organized more than the JS I write and understood it enough to edit it but couldn't really grok it. This explained just about everything.

Awesome, that is great to hear! :) I really like the way this structure works for thinking about frontend code. jQuery is usually written poorly and you end up with a lot of "spaghetti code". Glad this makes sense to you.


Chris, I'm really enjoying your screencasts but would like to make one suggestion; could you post the video file size for the episodes? I recently found myself on a mobile device with some time to kill and wanted to watch one of the episodes, but couldn't find a good way to tell how large the file was and wasn't sure if it would have eaten up all my monthly data or not. It's not a situation I find myself in often, but since I was in that position myself I figured I'd pass it along.

Thanks for putting so much hard work into your screencasts; I've enjoyed pretty much all of them and am looking forward to many great episodes!

Thanks,
A happy subscriber

That's a great idea. As far as the streaming video goes, the file size won't be exact because sometimes it switches between standard and hi-definition videos. I think showing the file size of the HD version or the download file (which is the original video I uploaded) would probably help.


This is actually similar to how I have been writing my jquery.

Recently, though, I've been using ES6 more than coffeeScript but being able to use classes on the front end has been so much nicer than the jquery soup I used to deal with.

ES6 looks fantastic and I just need to try it out soon. Are you using sprockets-es6?

Yeah I've used that which is just babel under the hood. Also used traceur, which I believe is googles transpirer.

ES6 is basically a lot of the features of cofeescript except with out white space parsing.

I still like coffee script in general and use it when I can. It still feels the closest to writing ruby on the front end.


@excid3:disqus: I really like the idea of using JavaScript objects to represent elements on the DOM. I implemented something very similar with menus instead of todos and it works well except for 1 issue I ran into.

When you call:


$.map $("li"), (item, i) ->
new Todo(item)

This only works on elements currently on the DOM. If you create a new todo with AJAX, that new todo will not have this functionality and you will have to do something like:


# app/views/todos/create.js.erb (JS off top of my head, so may be issues...)
$("#todos").append( $("#todo-<%= @todo.id %>") );
new Todo( $("#todo-<%= @todo.id %>") );

If we got rid of the JavaScript class and instead went with straight jQuery, we could benefit from using the "on" method which is "live" with jQuery and operates on dynamic elements as well.


# app/assets/javascripts/global.js.coffee (using turbolinks)
$(document).on "ready page:load", ->
$("li.todo")children("input[type='checkbox']").on "click", ->
# handleToggle method code...


This should apply the JavaScript logic to any newly-created todo items, I believe.

However, this "solution" loses all the power of using object-oriented-like programming with JavaScript classes to represent the DOM.

Do you have any thoughts on a solution to that kind of problem?

Only other thing I can think of so far is listening for whenever a new "li.todo" element is somehow added to do the DOM and attach the event handlers there, but I'm not sure if it's possible to capture a "new element" event.

Yeah, that's a great question. I generally take that first approach, or something like it. Sometimes rather than doing it on the response, I'll do this beforehand, but each time you'll need to instantiate the class for every record inserted. I didn't find it to be that much of an issue from building things like this, but it can be a little extra work. In any case, dynamically adding things like this without using something like React is going to usually entail some extra overhead like that.

@excid3:disqus: do you happen to know of any places for examples of using singleton classes like this for handling jQuery event handlers, etc...? I've spent a better part of my morning searching for ways to cleanup event handler code (aka, the jQuery "spaghetti code") into CoffeeScript classes, but didn't have much success.

I'm implementing my CoffeeScript code as singleton classes that operate on the DOM with interactions/events, but haven't really found good examples of this being done in a real application so I wanted to get some research before I jumped into a solution that later turns out to be a bad idea.

Just curious if you came across any good examples when you were making this screencast.

And one other thing I thought of, is you can sometimes do a hybrid approach, where you don't really uses an instance of each class, but more the class as a singleton representing whatever the current object is, doing all of it's work relative to the event handler. You can have more generic React-like classes that way that end up being able to take advantage of both the class and the live handlers from jQuery.


Great episode, the use of class is really interesting. I saw that you use a standard ajax request to change the todo status. I would have use a link to the same url with a "remote: true" to process this action. Would you mind explaining what is the rule of thumb regarding the use of the rails way VS the standard ajax is better ?.
Currently, I user remote true only when I have to reload a partial.
More contextual question : I have a user.attachment nested inside a user#update form. A delete link (using remote: true) proceed the @user.attachment.nil @user.attachment.save. Everything works as expected, but I'm wondering what is the best practice for reload this file field ? Since it's a nested form, I have to re-do a fields_for @user around the field_for attachment to avoid passing to the partial the "f" as a locals variable. It works, but doesn't look clean. Thank you in advance for your advice.


Chris, this is such a game-changer for me. I am actually looking forward to my next jquery feature to implement this... rather than dreading it like usual. As you describe, it puts you in the same headspace as you are in while doing normal rails model work.
Great stuff, mate!


Well, the reason is because that is not supported in any browsers right now. See: https://developer.mozilla.o...

You can only use modules if you're using a transpiler like babel / webpack to convert it to code the browser can understand today.

Yeah but I was not refering to import export of es6, I was talking about creating an auto invoke function that contains the other functions and returns an object you can use it as a Module (you don't need es6 for that)

Yeah, you could do that, but also coffeescript does much more than adding classes to Javascript. It added a lot of other things that ES6 has now come to include (like finally a decent way for string interpolation) so ES6 what people will generally be using these days over coffeescript anytime. Mind you this video is 2 years old.


I am actually trying to implement a whole frontend functionality with coffeescript

I have a `Purchase`, `Item` and `Product` objects in my coffescript file which I will use to do post request to my rails app


in the end javascript is an essential skill for programmers so it does not make sense always do everything with ruby
In the last year I always avoided using javascript for the frontend logic, but this often makes me write bad code, not follow restful and Object Oriented design. 
I can not figure this out so I wrote a StackOverflow post to receive other developers opinion
https://stackoverflow.com/questions/49914376/coffeescript-json-object-for-ajax-request

This video was great. I built a nice functionality based on this lesson and you can check the source code on github. 
Everything is explained in this stackoverflow post https://stackoverflow.com/questions/49914376/javascript-objects-retrieve-child-class-variable

Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 20,000+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.