Skip to main content

Posts

Showing posts with the label JavaScript

JavaScript on Rails 2016

Whilst I am primarily a JavaScript programmer, my framework of choice is Ruby on Rails. A lot of JS guys like Node or other frameworks which are JS all the way through, but there's a lot to like about Rails, even in 2016 and it's worth learning another language (Ruby) or two (SQL) in order to get the best environment on which to write your JavaScripts. Before I say what I like about Rails though, I will take you through what I don't like just to balance things out. What I don't like about Rails Asset Pipeline still does not let you use ES6 Modules.  Even at this late stage, one still cannot access ES6 Modules in Rails in a "Railsy" manner. You can either bypass the whole Asset Pipeline or else separate out the JS using Webpack or whatever, but in a standard Rails project, the fact that the asset is generated with unique hash in the file name before the extension pretty much nullifies its use for ES6 Modules which need a static location to store the fi...

React: Viewless components

I have been using Facebook's React library for a while now (https://facebook.github.io/react/) and I like it for the most part. The most controversial aspect is the fact that the View is mixed into the Logic using what looks like HTML in the "JavaScript" file using JSX. While it is possible to write React components in plain JavaScript, you must include a render() method. However, it is actually possible to do the following... (in ES6 syntax) render() {   return (null); } Now, why would you want to do such a thing? I thought the whole point was to use React to tie together your view and logic layers (and shouldn't you be abstracting out your heavy logic to plain JS classes?). Well, the main reason you might want to do it is because of React's component lifecycle. In my case, I wanted to trigger some JS to run when the component was loaded, and I happen to be using Turbolinks and React-Rails in a Rails project. This JS had ...

Testing React components with Jasmine in Rails with the react-rails gem

So in my latest project, we are using Ruby on Rails and the react-rails gem to implement our React components. While react-rails is fine for the most part (and for simple components), there is a severe limitation in that you cannot use ES6 modules (i.e. using the import and export classes) because of the way asset-pipeline works. Asset-pipeline precompiles all your JS into one mega JS file and therefore doesn't allow you to call individual JavaScript components in separate files (because they don't pushed to the server). This is a severe problem which I hope gets fixed soon, but in the meantime don't hold your breath. There are workarounds using Browserify and/or Webpack, but they are messy (Google them for more info). In any case, react-rails does allow simple React components in Rails apps and it mounts them all in the window/global namespace, so you can use a good 75% of React within a Rails application. So now, we come to testing... Facebook uses a testing f...

Mixins in ES6

I had been looking for a good way to do mixins in ES6. Looks like I finally found one. http://raganwald.com/2015/06/10/mixins.html Essentially, create the mixin as a const Use Object.assign to add the properties to the Class const BookCollector = { addToCollection ( name ) { this . collection (). push ( name ); return this ; }, collection () { return this . _collected_books || ( this . _collected_books = []); } }; class Person { constructor ( first , last ) { this . rename ( first , last ); } fullName () { return this . firstName + " " + this . lastName ; } rename ( first , last ) { this . firstName = first ; this . lastName = last ; return this ; } }; Object . assign ( Person . prototype , BookCollector ); (I am copying and pasting this for personal reference in case the original site link goes down).

ECMAScript 6

Today is a rather significant one for me as JavaScript/Rails programmer because Sprockets ( https://github.com/rails/sprockets ) upgraded to version 3 meaning I can now use the Sprockets-es6 gem ( https://github.com/josh/sprockets-es6 ) to transpile ES6 JavaScript to ES5. Now to those that didn't understand the last paragraph, here's what it means... The language we commonly call JavaScript is actually formally known as ECMAScript ( http://en.wikipedia.org/wiki/ECMAScript) . Since 2009 all the major browsers have been interpreting ECMAScript version 5. In fact they mostly still do. Version 6 is due to be formalised any day now (well, June 2015) which means that a whole new slew of functionality is due to be added to the language (class constructors, formal inheritance, fat arrows, etc...). Browser makers will start implementing these new features once the spec is complete. All of this sounds great, but for 2 things 1) I want to start using ES6 today 2) Even if the ne...

Checking performance in EaselJS apps

So one of the great things about EaselJS  is the fact that you can create Flash like games in JavaScript. I have been doing so on www.activememory.com for the last couple of years. Unfortunately, it came to our attention that on some systems, the games ran rather slowly. According to their own docs, they admit that the time between ticks might be greater than specified because of CPU load ( http://www.createjs.com/Docs/EaselJS/classes/Ticker.html#method_setInterval ). So, is there any way we can track the actual time between ticks on a real system? Fortunately, yes, we can. On each element that uses the ticker, you can set up an addEventListener and set the method you want to fire on that interval. createjs.Ticker.addEventListener('tick', tickListener); In the method itself you will want a few instance (or global) variables this.previousFrameTime this.totalFrames this.totalFrameTimes as well as a local variable currentFrameTime On each tick, we get the cu...

IE console.log(). It works, except when it doesn't...

So I made an interesting discovery today. console.log() in IE9 only works when the console is open! As a web developer, and especially a JavaScript developer, the most useful tool in your arsenal is console.log() . And while you should (for the most part) remove any console.log() calls from your code as soon as you have finished debugging, sometimes your library code might contain it, or other times if you are writing a framework for an intermediary to use, you might leave a couple of messages for your intermediaries using console.log() . console.log() first made an appearance in Firefox's Firebug (or at least that is when I first noticed it) and has been in most major browsers, including Internet Explorer since version 8. Whilst developing, I have happily had my console open so I can debug things. Anyways, fast forward to the current app I am working on. I am lucky enough to be working on a project that uses HTML5 canvas and the project I am working on is used by a game...

JSON caching with Rails

So the other day, I needed to cache an action which was basically a proxy action to return JSON. Basically, 3rd party company X has an XML API for it's deals. Ideally we would use JavaScript to pull the feed, but unfortunately, the feed is using XML which means we need to use the server to pull this "deal" and then reformat it in JSON for our site to use. To render the JSON we were using a render call render offer.to_json It can get expensive to pull this deal over the wire every time, so we looked into using caches action and set it to expire in 5 minutes (because that is how often the deal feed updates). caches_action :index, :expires_in => 5.minutes (Oh, also we need to turn caching on in dev to see this happening) config.action_controller.perform_caching = true While this worked fine for the first call, I noticed that in the subsequent calls, the application type was being set to 'text/html' instead of 'application/json'. This was causing the ...

Stubbing out AJAX methods

I have always had trouble with the standard way of testing out AJAX calls with QUnit. There are a number of problems with it. 1) You have to stop and start the tests while waiting for an AJAX response 2) If you don't give a large enough gap, then your test may fail while waiting for an AJAX response. 3) If you have too large a gap, it slows down your tests However, today I found this cool method of dealing with it. http://lostechies.com/johnteague/2009/02/10/another-way-to-test-ajax-methods/ Essentially, you stub out jQuery's $.ajax() method with your own for your tests (as for unit testing, you really just want to test your code around the ajax method, not test jQuery's ajax method). In my own case, I was using $.ajax and not $.getJSON. It took me a little while to work out I had to create a trigger for the success() function rather then callback() as mentioned in the article. var stubbedAjax = function(settings){ settings.beforeSend(); // s...

Patterns

Just a couple of links today (more details to follow). I found a great reference for JavaScript and jQuery Design Patterns here: http://addyosmani.com/resources/essentialjsdesignpatterns/book/ Also, I learned about the Presenter pattern today. We were having a discussion at work about what to do with presentation logic in Rails. On the one hand you don't want it in the controller because you want to keep your controllers thin, on the other hand you don't want it in the models either because it's presentational. You can't put it in the erb because they shouldn't contain logic. Enter the Presenter Pattern: http://donttrustthisguy.com/2008/05/29/using-presenters-in-rails-3/ http://blog.jayfields.com/2007/03/rails-presenter-pattern.html Enjoy your homework!

Reading AJAX XHR File Uploads in Sinatra

So in my last post I talked about Drag and Drop file uploading with qq.FileUploader ( http://valums.com/ajax-upload/ ). Anyways, I discovered that qq.FileUploader uses AJAX/XHR to post the file uploads. What I also discovered is that these file uploads need to be handled in a separate manner from a regular file upload form post. A normal form post (when File upload XHR requests are not available on the client like in Internet Explorer) passes in the following parameters params: {"qqfile"=>{:type=>"image/png", :head=>"Content-Disposition: form-data; name=\"qqfile\"; filename=\"bb2.png\"\r\nContent-Type: image/png\r\n", :tempfile=># , :name=>"qqfile", :filename=>"bb2.png"}, "upload_type"=>"rec", "id"=>"24db8cab-285a-abcb-cb47-4daceee977ca"} Sinatra then reads the :tempfile and :filename parameters to write the file to the server name = params[:qqfile][:fil...

Ajax File Uploading

You know that cool Drag and Drop file uploading they have in Gmail? You know, the one where you can drag a file from a folder onto a webpage and upload it? Have you looked at the code? Looks complicated huh? Well, thankfully, for any cool bit of JavaScript functionality out there, someone has created a plug in (most likely in jQuery, but not always...). http://valums.com/ajax-upload/ is (as far as I can tell) a library agnostic JavaScript plug in which factors out all the hard work. All you have to do is put in a "dummy" element on to which to hook (never end a sentence in a preposition) and then put in a small snippet of code to turn it into a file upload element <div id="file-uploader"> <noscript> <p>Please enable JavaScript to use file uploader.</p> </noscript> </div> var uploader = new qq.FileUploader({ // pass the dom node (ex. $(selector)[0] for jQuery users) element: document....

Node.js

I had a quick look at Node.js . Looks very interesting (kind of like a JavaScript version of Sinatra ). Now all I need to do is find out if they have any frameworks...

Browser Highlighter Firefox extension / plug in

On my site we noticed that some of our users had some JavaScript problems which was affecting content editing. After a bit of nosing around we found the problem was a Firefox extension called The Browser Highlighter. This extension was created by eBay and it injects some JavaScript into the page which can affect the JS in your site. You can view this JavaScript in Firebug (it is in the script tag added just after the head tag) What follows is a means of detecting this extension so you can protect your code from it. Unfortunately, Mozilla Firefox does not provide an API into detecting browser extensions, but there is a work around. If the extension injects a graphic into the page (which this one does), it does so by referencing it from the chrome protocol. i.e. chrome://shim/content/compareLang-1/eBayCompareIcon_yellow.gif as opposed to the normal http protocol So all you have to do is reference this image and place an onload event on it. If the event fires then the extension is install...

jQuery: When does a library become a language?

jQuery is a great JavaScript library which allows web developers to write cross platform code, but some of its syntax looks like it is based more on Ruby than JavaScript. When does a library become a language? So first of all, what is the difference betwen a programming library and a programming language? A programming language is a means by which we (as humans) can give instructions to a computer to get it to do various tasks (algorithms, computations, etc...). They are largely artificial constructs created for human readability which then need to be compiled or interpreted into actual instructions which the computer can then carry out. A compiler turns a program into machine readable instructions ahead of time (compile time) where as an interpreter does so on the fly (runtime). Languages such as C and Java are generally compiled and JavaScript, Perl and Ruby are generally interpreted. While there is no real reason why this has to be the case, these factors normally affect the syntax...

Suppressing and Logging JavaScript Error messages

When it comes time to run your fancy AJAX site on production, you may find that there will occasionally be minor JavaScript errors (possibly from 3rd party sites, never your own of course) which will not only prevent your scripts from running but may also pop up some warning boxes on the end users' systems (especially if your target audience is made up of web developers who have "Disable JavaScript Debugging" unchecked). Even if the user does not have debugging turned on, they may still see the error symbol in the status bar (and this does not exactly put their fears at ease, especially if they are trying to make a cash transaction). Fortunately, you can suppress these error messages by using the following JavaScript code function noError(){return true;} window.onerror = noError; Essentially what this does is catch any JavaScript errors and passes them to a null function. You should probably wrap this in a conditional which will only run on production and staging because ...

Real MVC for the web

I recently read an article which talks about writing MVC for the web using jQuery ( http://welcome.totheinter.net/2008/08/05/mvc-pattern-for-the-web/ ). In any case, the author proposes building a full MVC controller in JavaScript (the example article is still in progress), which is interesting, but I think in some ways it is a little misguided, for I believe that the front end of the web is already MVC. Model = HTML (provided it is written semantically and not structurally) View = CSS (updating the style) Controller = JavaScript As long as you follow the principles of Unobtrusive JavaScript and keep your (X)HTML clean then you have MVC built in. XHTML is a form of XML after all (and XML is used to represent data/model). Just a thought...

Unobtrusive JavaScript and href="#"

Back in the old days of inline JavaScript, people would often attach JavaScript functionality to links either by using: <a href="#" onclick="doSomeJavaScript()">Click Here</a> or by using <a href="javascript:doSomeJavaScript()">Click Here</a> Anyways, there are problems with both. In the first instance, the user will get booted up to the top of the page in some browsers (that's what href="#" basically does). The second instance is better, but it is inline and that is something we want to avoid. In the Unobtrusive JavaScript world we would basically have to use the first instance because the "a" tag will not display as underlined in some browsers without an "href" attribute. Or would we? I am not really sure where the metaphor for using links as actions came from, but as long as it is there and people are used to it we will often get designs from UI designers using them as such. Links are really supp...

Unobtrusive JavaScript and the "lang" attribute

One issue that has come up in using Unobtrusive JavaScript is how do you assign instance specific data to the element. For example, in the old days (pre UJ) you could iterate over a bunch of objects (each with it's own ID) and hard code the ID into the on{Event} attribute i.e. <% for item in items %> <div onclick="someFunction(<%= item.id %>)">Click here to select item</div> <% end %> But in UJ, on{Event} attributes are no longer considered good practice. If only there was a way we could somehow encode the id with the HTML like we could in Flex (Flex supports dynamic attributes on objects). You can assign a dynamic attribute using JavaScript, but putting a script tag into the loop seems very inelegant and against UJ principles. The other way would be to render all the objects in JavaScript first and then re-render them in HTML. This does seem rather wasteful in terms of processing however and full of index dependencies when you want to merge ...