Refactoring Your jQuery Code with Objects in Coffeescript Discussion
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?
@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.
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)
https://github.com/fabriziobertoglio1987/sprachspiel/blob/3ab451d16b1a7ea83f919158c7983bdae8c2e25b/app/assets/javascripts/products.coffee
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.
https://stackoverflow.com/questions/49914376/coffeescript-json-object-for-ajax-request
Everything is explained in this stackoverflow post https://stackoverflow.com/questions/49914376/javascript-objects-retrieve-child-class-variable