Migrating to TypeScript from ES2015 for AWS Lambda

Posted by on Oct 12, 2016 in AWS, Cloud, JavaScript

I was recently building an skill for the Amazon Alexa platform (think Amazon Echo, Fire tablets, Echo Tap etc). Like anyone writing JavaScript today I naturally levitated toward some of the syntactic goodness that ES2015 offers – arrow functions, let variable scoping, string literal templating, default parameters etc all of which make JavaScript a much, much nicer language (and much, much closer to C# incidentally which is where the language seems to be heading long-term looking at current and new functionality. Alas, I digress!). I had the skill up and running locally (bridged via an Express.js node front end for testing) and everything was working well. Then it came the time to upload my skill to the amazon developer portal and migrate my function to AWS Lambda. This is where the fun started – it turns out Lambda uses a fairly dated version of Node.js that doesn’t support much of the ES2015 specification. This left me faced with two options – strip out all the ES2015 code and rewrite using vanilla JavaScript or make use of our friend, Typescript. To be honest I should have gone down the TypeScript route from the offset; in hindsight I’m not sure why anyone would write straight JavaScript nowadays when the TypeScript transpiler does such a great job of both supporting new functionality and also outputting compliant ES5 code. The task of migrating from JavaScript was as easy as 1-2-3: Rename all my .js files to .ts Install tsc from the command line (npm install –g tsc) and create my tsconfig.json with the list of files in my project Run typescript in watch mode (tsc –w) to get it to watch for changes to save (my lazy hands) having to recompile manually Once this was done I was free to do nothing more and I already had fully “Lambda compliant” JavaScript that I could use. However, the TypeScript compiler can do so much more for me, so I spent a little time going through my code adding in types to all my parameters, created an object interface so TS knew the type of data I was passing around on properties on the object (this also greatly improved Intellisense in VS Code I might add) and pulled down some typings for the third party libraries I was using. Migration was such a smooth and painless experience and I’m now in a much better place than I was prior to the conversion. I have compile time type checking, I get to use the much more elegant and succinct ES2015 syntax and I have a much better development environment through the “knowledge” TypeScript now has about my...

Read More »

Using newer ES6 features in Node

Posted by on Jul 8, 2016 in JavaScript, WebDev

If you’re writing Node and want to use some of the newer ES6 features then you may have an issue running some of the newer features that haven’t made it into the V8 engine integrated with your specific version of Node. I came across this recently when using the new default parameters feature. Using the latest stable version of node (4.4 at the time of writing), the following code was throwing an error at runtime: function doSomething(param1, param2, callback=()=>{}) { //Do stuff } 123 function doSomething(param1, param2, callback=()=>{}) {  //Do stuff} Essentially I wanted the callback parameter to be optional so that I could supply it if I wanted to and it would get invoked, but not throw any errors if not. Using default parameters meant I didn’t have to clutter up my code with lots of null checking and ugly if statements. This is a pattern I use quite a lot in ES6 and feel it leads to much cleaner code. Node was complaining of the unexpected token callback=() as it didn’t understand the assignment of the anonymous function to the callback parameter (i.e. the default value). After a bit of digging it became clear that there were two ways around this problem, both of which worked for me. Initially I sidestepped the issue by using the new harmony feature flags, which turns on the experimental features in unsupported versions of v8. Thus, in my case simply adding the default-parameters flag worked around this problem: node --harmony-default-parameters index.js 1 node --harmony-default-parameters index.js However, the harmony feature flags aren’t really recommended as its putting alpha level code into the fray. The longer term solution (and the route I took) was to upgrade node to the newest version. Again, at the time of writing this is 6.3.0 which has a much, much broader level of ES6 compatibility due to its newer build and newer version of V8. Problem solved. ES6 and...

Read More »

What is the Shadow DOM?

Posted by on Jun 22, 2015 in JavaScript, WebDev

Shadow What? I’ve seen lots of queries on SO and various programming forums regarding the Shadow DOM. It seems lots of developers know that it exists, but many of those do not understand its purpose or significance. Moving forward, Shadow DOM is going to play a significant role in web development, not least as a core part of the web components specification. So What is it? At its highest level, the Shadow DOM is an emerging standard that allows you to encapsulate content (not just HTML) from the main document. This means you can ‘embed’ styles and markup completely decoupled from the rest of the web page and not have to worry about naming collisions, JavaScript conflicts or other quirks commonly found on large pages that use multiple frameworks from sources. So what is the problem? Imagine, if you will, a fancy all-singing, all-dancing video player. This reusable component if made available on the web for inclusion on your page (or even the native HTML5 video player supplied by the browser vendor). There are few scenarios where you would want other styles on the page to affect the core elements of the player (e.g. play/pause button) and you don’t want to have to worry about elements on your page conflicting with that of the video player. This is a very real worry but this is exactly the kind of problem the Shadow DOM is intended to solve. How does it work? At a simple level, with Shadow DOM any element can have a new node called the shadow root. This is the isolation boundary assigned to that individual element. The hosting element becomes the shadow host. This isolation provides great protection but also allows you to access the parent document via JavaScript so other parts of the page remain accessible (e.g. form controls) Can I start to use it? At the time of writing, we’re some way from full browser support. There are polyfills available (e.g. platform.js (https://www.polymer-project.org/0.5/docs/start/platform.html)) but as always, check the status on CanIUse.com for up-to-date...

Read More »

POST file (and form data) using Fiddler

Posted by on Jun 16, 2015 in JavaScript, Other

I was recently trying to upload a file to a locally developed Node.js API using Fiddler to test some upload functionality. Now uploading a file on its own is trivial in Fiddler, thanks to the ‘Upload file…’ link in the composer window. However, I wanted to add some additional POST data to the request and this stumped me for a while on the exact syntax that fiddler wanted. When you choose a file from the ‘Upload file…’ link you’ll notice that fiddler replaces your body content with something similar to the following: ---------------------------acebdf13572468 Content-Disposition: form-data; name="fieldNameHere"; filename="Panthera.jpg" Content-Type: image/jpeg <@INCLUDE *C:\Users\leejones\Pictures\Panthera.jpg*@> ---------------------------acebdf13572468— 123456 ---------------------------acebdf13572468Content-Disposition: form-data; name="fieldNameHere"; filename="Panthera.jpg"Content-Type: image/jpeg <@INCLUDE *C:\Users\leejones\Pictures\Panthera.jpg*@>---------------------------acebdf13572468— I tried all combinations of prepending and appending form data but my node.js app was receiving none of it. Eventually I stumbled on the solution which is not at all obvious. You need to repeat the Content-Disposition sections for each form field you want to upload: ---------------------------acebdf13572468 Content-Disposition: form-data; name="field1"; value ---------------------------acebdf13572468 Content-Disposition: form-data; name="field2"; value2 ---------------------------acebdf13572468 Content-Disposition: form-data; name="fieldNameHere"; filename="Panthera.jpg" Content-Type: image/jpeg <@INCLUDE *C:\Users\leejones\Pictures\Panthera.jpg*@> ---------------------------acebdf13572468— 123456789101112 ---------------------------acebdf13572468Content-Disposition: form-data; name="field1"; value---------------------------acebdf13572468Content-Disposition: form-data; name="field2"; value2---------------------------acebdf13572468Content-Disposition: form-data; name="fieldNameHere"; filename="Panthera.jpg"Content-Type: image/jpeg <@INCLUDE *C:\Users\leejones\Pictures\Panthera.jpg*@>---------------------------acebdf13572468— The other thing I forgot to do was change the automatically generated name=”fieldNameHere” to the actual parameter name that my node.js app was expecting. Once these niggles had been fixed, it worked like a...

Read More »

Grunt from the command prompt in Windows

Posted by on May 20, 2015 in JavaScript

If you’re planning to play about with Grunt on Windows any time soon, chances are you’ll find a tutorial online which tells you to install grunt globally as follows: npm install –g grunt 1 npm install –g grunt This will run just fine, but when you next run grunt you’ll get the lovely error: 'grunt' is not recognized as an internal or external command 1 'grunt' is not recognized as an internal or external command Whats going on here then? Turns out Grunt itself is no longer installed globally, but its command line interface (CLI) is. The CLI is simply there as a GLOBAL means of launching a locally provisioned grunt. Therefore all you need to do is amend the command to: npm install –save-dev grunt npm install –g grunt-cli 12 npm install –save-dev gruntnpm install –g grunt-cli that way, the next time you run grunt <anytask> 1 grunt <anytask> from the command line, the CLI will invoke the locally installed grunt instance and you should be good to go. If in doubt, just follow the official grunt.js getting started...

Read More »

[Node.js] connection.session.store cannot read property of undefined

Posted by on Aug 11, 2014 in JavaScript

I recently ran into a problem whereby when attempting to use session-mongoose for session storage via MongoDB in a Node.js application, I was being hit with the error: connection.session.store cannot read property of undefined 1 connection.session.store cannot read property of undefined After Googling this with Bing and some other search engine jiggery-pokery I came up blank. Lots of references from a few years back which were down to a number of factors, but nothing relevant to my particular error. Looking at my code: var MongoSessionStore = require('session-mongoose')(session); var sessionStore = new MongoSessionStore({ url: credentials.mongo.development.connectionString }); app.use(require('express-session')({ store: sessionStore })); 12345 var MongoSessionStore = require('session-mongoose')(session); var sessionStore = new MongoSessionStore({ url: credentials.mongo.development.connectionString }); app.use(require('express-session')({ store: sessionStore })); And looking at the Github page for session mongoose there was nothing obviously wrong with what I was doing. Thus I started poking around in the node_modules folder to try and find out what is going on. It turns out that as Express and Connect have been largely decoupled, the Session middleware I no longer party of the connect object. However, session-mongoose hasn’t been updated to reflect this and thus it was still referencing connect.session.store. The Session object is no longer a property on the connect middleware, so the simple fix was to change the passed in parameter to session-mongoose function to connect.Store (/node_modules/session-mongoose/index.js:266). As is often the case, Node.js is still a very immature technology and the rate of change if its components and add-ins continues to cause compatibility and dependency problems, despite the best efforts of NPM.  ...

Read More »