Friday, September 23, 2016

React Item Templates

With the future of Angular 1.x development coming to a head, our team started looking at other front end technologies that could potentially live side by side with angular 1.x and eventually (a long time down the road) replace our angular 1.x app completely.  We considered a few frameworks and ended up settling on React.js.

Shamelessly stolen picture from work HipChat room. 

One of the problems I recently worked on required a multi selectable list of items.  The catch was that I wanted to allow the template of the item to customizable while allowing for most of the functionality to be the same.  I realized that you could pass in a function as a property, and wondered why not a react component class.  It is essentially a function.  I tried it out and it ended up working.  Here is a JSFiddle with using that idea:




So in the container class, CustomList, I accept an optional parameter called itemTemplate.  It should be a function.  I then set a variable called ItemTemplate to be either the itemTemplate passed in or the DefaultRow class.  The key thing here to note is that you must make your ItemTemplate variable name capitalized.  React has a convention that you custom elements need to be capitalized.  I can then just pass whatever properties to each item instantiation and each one can format however they like.  Super Easy!

Monday, September 21, 2015

Learning ECMA Script 6: Arrow Functions

If you are familiar with a language other than JavaScript, there is a good chance that language already supports something similar to => functions.  In ES6 they are called arrow functions (or FAT arrow functions) and 9 times out of 10 they replace anonymous functions.  There is one major case where they differ, and I will get to that in my last point.




The first way to use an arrow function is the same any way you would use function (param1, param2, ...) { ... }.  Instead of that you would write the following:

   
(param1, param2, ...) => { ... }; 

It is pretty straight forward and it is shown in the example below:

var closureVariable = 'foo';
var test1 = () => {
    var innerVariable = 'bar';
    // look ma!  Closure still works.
    return closureVariable + innerVariable;
};

document.getElementById('test1').innerHTML = 'Test 1: ' + test1();


As you can see, no magic there.  It is simply replacing function (param...) with (param...) =>.  Most places you have anonymous functions are in callbacks and promises.  While it was super weird at first using them I found my code to be easier to read now (especially jasmine unit tests) and rarely write the word function anymore.

Now if you have a function that is one line and returns something, you can make the arrow function one line.  Imagine you were using the lodash function map that will "map" your current array into another one.  You just need to supply the function to transform each object.  Imagine you just wanted a property out of that array like name.  Before you would need something like this:

    
_.map(list, function(item){ return item.name;});


Now you can write this:

    
_.map(list, item => item.name);


item.name is implicitly returned since it is not surrounded with curly braces.



So you might ask, that's fine, but what if I want to return an object?  I need curly braces for that!  The answer is, Yes you do!  So to do this you would wrap your object in parenthesis and the above will still work.

So you would write the following:

    
_.map(list, (item) => ({ id: item.id, name: item.name}));





There one major difference between anonymous functions and arrow functions is how this is defined in the function.  Arrow functions now have Lexical this. 

What does this mean?  The easiest way would be to show you the difference in these two examples:

Suppose I have the following object.
  
var solarSystem = {
        planets: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto'],
        star: 'Sun'
    };


Now I want to add some function to that object that does something to the array, and references some other property on the object.

    solarSystem.performOperation = function(){
        this.message = '';
        this.planets.forEach(function(p, i) {
            this.message += p + ' is planet number ' + (i + 1) + ' from the ' + this.star + '.  ';
        });
    };


What happens if you run this code? You will get the following:  

solarSystem.message === ''; //true

Why? This is because in the forEach function 'this' is defined as the window object. So the window object will have a message property on it that contains the following:  

window.message = 'undefinedMercury is planet number 1 from the undefined. Venus is planet number 2 from the undefined. Earth is planet number 3 from the undefined. Mars is planet number 4 from the undefined. Jupiter is planet number 5 from the undefined. Saturn is planet number 6 from the undefined. Uranus is planet number 7 from the undefined. Neptune is planet number 8 from the undefined. Pluto is planet number 9 from the undefined. ' 

 
However if you write the same code using arrow functions like in the fiddle below you will get the desired result.


Cheers!

Part 1 - Math & Numbers
Part 2 - New Parameter Features 

Tuesday, July 28, 2015

Learning ECMA Script 6: New Parameter Features

ES6 has a few new features when it comes to working with parameters.  To get these examples working, you most likely will have to use Firefox.

Pluto Hearts ES 6 Features

Default Parameters

Allowing for default parameters is a new feature being added into ES6, and are really simple to use.  When defining a function & specifying the parameters just add an equal sign and the value and you want to default it to and BAM! DONE!  So you would write your function like this: 
function defaultParam(foo = "bar"){};   
Now if the first parameter passed for foo is undefined then it will default to "bar".  However if it is null then it will be passed in as null!  Note that you can actually explicitly send in undefined it WILL use the default value.  You can also call functions to get the default value for a parameter, but be aware that the function will NOT be called unless undefined is passed in for that parameter.  

Rest Operator


The rest operator “…”is used when you define a function and works similarly to something like ‘varargs’ in Java or the ‘params’ in c#.  If placed before the last parameter in a function definition it turns it into an array and places all arguments that aren’t accounted for into the array.  You would write your function like this:
function restParam(foo, ...bar ){};  // bar is now an array



Spread Operator

The spread operator "..." is the same as the rest operator syntax wise, but used differently.  While the rest operator brings parameters together, the spread operator blasts arrays apart.  So the spread operator can be used to “spread” and array into individual arguments for a function call, or it can be used to “spread” an array out for use in another array definition.  It would be used like this:
function spreadParam(foo, bar){}; spreadParam(...["foo","bar"]);
One thing to note is that also works on strings as well.




Cheers!

Friday, July 10, 2015

Learning ECMA Script 6: Math and Number Features

At work we are currently preparing setting up our environment using tools such as babel to allow us to work with the newest JavaScript features without worrying about browser support.  So I am going to start taking a look at some of these new features and hopefully start incorporating them into my daily repertoire.

In this post I am going to take a look at the Number and Math features which are pretty easy, and mostly already implemented by modern browsers.


While Math can be scary, using these new features don't have to be.  We will start with the Number features and then move into the Math ones.

Numbers:

1. Support for octal and binary notation.  You can now specify numbers as octal (0o###), or binary (0b###);   So 8 (0o10) + 2 (0b10) + 10 + 16 (0x10) = 36



2. Support for octal and binary strings.  Since octal and binary formats are now supported you can pass those formats into the Number() function and it will convert it into an integer.  In the fiddle below the variables are converted to numbers using the Number function and we obtain the same result.


3. Number.EPSILON is a new constant that represents the difference between the smallest possible number greater than 1 and 1.  So essentially the smallest possible number that can exist greater than zero.  It represents 2.2204460492503130808472633361816E-16.  From what I can tell it is most useful in testing equality of decimals.  So instead of doing .3 - .2 - .1 === 0 (false) you can do Math.abs(.3 - .2 - .1) <= Number.EPSILON


4. Number.isInteger is a new function that lets you know if a number being passed in is an integer.  If it is not an integer or not a number then it will return false.


5. Number.isSafeInteger is similar to the function above, but also checks to see if the number is "safe".  Due to the way that numbers are represented in JS, there are max and minimum numbers that are "safe", and any numbers beyond that are potentially off.  What do I mean by "off"?  Essentially two or more integers beyond the max or minimum are represented by the same JavaScript integer.  Check out the third line in the fiddle below for wtf I am talking about.


6. Math.sign will return -1, 1, 0 (or -0....), or NaN based on the value passed in. 

7. Math.trunc will turn the number into an integer which will essentially round down if greater than 0 or round up if less than 0.



8. There are new trig methods such as Math.sinh, Math.cosh, Math.tanh, Math.asinh, Math.acosh, Math.atanh.  There is also a new Math.hypot function that calculates the square root of the sum of the objects. 

9.  There are also some new exponential and root functions available.  Math.cbrt returns the cube root of the number passed in.  Math.expm1 and Math.logp1 are similar to the Math.exp and Math.log, but from what I can tell by reading online they are more accurate when it comes to numbers close to 1. 

I believe that covers most if not all of the major changes in ECMA Script 6.  If I forgot something let me know and I will make sure to update the post.

Cheers!

Thursday, June 25, 2015

Creating ES6 JSfiddles with Babel

One of the things I’ve wanted to start to start learning is what is new in ES6.  There are a lot of new features in ES6 that are pretty awesome.  There are some that can even be implemented today using other libraries or polyfills such as promises.  However, for other features it can be harder to implement.  

The good news is there are libraries out there that will compile your ES6 script into backwards compatible JS.  The one I am looking into is Babel  https://babeljs.io.  Babel would typically be set up in your development/build process like any other compiler, but this one would theoretically fade away and leave you with ES6 scripts when browsers catch up to it.  

So to get started playing around with ES6 scripts, Babel has provided a live editor here: https://babeljs.io/repl/ which is nice.  However that doesn’t let you save anything, or show it off in a blog, etc.  So I went to see if JS fiddle has any out of the box support for Babel, and found it doesn’t.  I knew that Babel had a client side compiler (which shouldn’t obviously be used for production), so I tried to find that listed somewhere in a CDN.  I couldn’t find it, so I decided to see if I can reference it via google drive.  After some time investigating and finding this site I found how I was able to do it http://www.komku.org/2013/08/how-to-host-javascript-or-css-files-on-google-drive.html.  You are only allowed to reference files with a .js extension so I had to use method 1, and I generated the following url https://www.googledrive.com/host/0B4QQSpfhQZN5bXdTVTI0VFpjZW8/browser.js. 

    
Once you have it listed as an external resource on the JS Fiddle you can then create <script> blocks with the type of text/babel in your HTML area.  Once babel loads it will automatically compile those blocks and you are good to go!

Cheers!

Thursday, June 11, 2015

Project Euler

A couple years back I started on my first project Euler problem, and just a bit ago I finished my 50th problem.   If you aren't familiar with Project Euler, it is essentially a bunch of math problems that you solve programmatically, but you can read more about it on the site.

I didn't know until this blog post.

I really enjoy working on these challenges.  The problems typically require good problem solving, efficient algorithms, and good use of data structures.  So these types of problems are great for learning a new language, practicing an old one, preparing for an interview, or just honing your coding skills.  I have become fairly decent in Ruby by working on these (and a few other projects) to the point where I can pick it up after a few months of not using it and not miss a beat.

I might switch up languages soon.  I have always thought about trying out a true functional language, just for fun.  Regardless,  I plan on solving problems every so often to keep my skills sharp.  You can see all of my solutions (good and bad) on github here.   Also if you try it out and like it, you can add friends on project Euler to track each other's progress.  Add me with the following key 517763_1aef854359e6e315b4f1e358b8544e78 and I will add you back.

Cheers!




Friday, May 8, 2015

Using HTML5 Canvas to Create a Transparent Image.

I recently have been working on learning some threejs stuff and trying to understand 3d concepts in general.  One of my favorite things is looking at 3d renderings of planets and other cosmic things.  So I found this post that talks about how he created the planets.  He uses the textures from planetpixelemporium for his planets.  Beyond the simple textures there are textures that define the bump map for rocky planets, textures for specular which defines the reflectiveness for each area, textures for clouds, and even textures for rings.

While I was going through his blogpost and his code, trying to make sure I understood everything he was saying, I came across this:
We build canvasCloud and use it as texture. It is based on the jpg images you see above: one for the color and the other for the transparency. We do that because jpg doesn’t handle an alpha channel. So you need to make the code to build the texture based on those images. 

I was super confused, and I apparently wasn't the only one based on his comments.  So armed with just his code, and google I set out to see what the deal is with multiple jpegs and transparency.  I found all kinds of interesting things out there and why people would write code doing this instead of using a png or another format that supports transparency like was done for this android app, was done for a game in JS, and this interesting trick that XORs two images to get a transparent one.

So armed with reasons why I wanted to visualize what this actually looks like when we go through the data and merge the two jpegs into an image with alpha.   I originally wanted to do this all in jsfiddle like I normally put my examples, but unfortunately jsfiddle doesn't support hosted images, I didn't want to pay one of the other online sandboxes to host them, and you can't look at the image data in a canvas that is from a different domain.  So I put this on a website I have been playing around with for a bit, so you too can see it in action.  The source is on github here.

To get this to work we will use 3 canvases (these don't have to be in the DOM to work).  One for the source image, one for the alpha (transparency) image which is all greyscale, and one for the destination.  We then load the two images we want by creating Image elements for each of the images, setting the src to the appropriate image, and then handling the onload event of each image.  The code looks like this:

    function loadImages(sourceImageUrl, alphaImageUrl){
        sourceImg = new Image();
        sourceImg.addEventListener("load", function(){
            sourceCanvas.height = sourceImg.height;
            sourceCanvas.width = sourceImg.width;
            sourceContext.drawImage(sourceImg, 0,0);            
            alphaImg = new Image();
            alphaImg.addEventListener('load', function(){
                alphaCanvas.height = alphaImg.height;
                alphaCanvas.width = alphaImg.width;
                alphaContext.drawImage(alphaImg, 0, 0);                
                startOverlay();
            });
            alphaImg.src = alphaImageUrl;
        });
        sourceImg.src = sourceImageUrl;
    }


Once that is done and we have the images loaded on the two canvases we will need to loop through the image data and copy over the RGB components from the source canvas and compute the alpha based on the brightness of the greyscale with white (255) being completely transparent, and black (0) being completely opaque (you can make this up however you want realistically).  Here is the code for that:

function startOverlay(){
        destinationContext.clearRect(0,0, destinationCanvas.height, destinationCanvas.width);
        
        var sourceData = sourceContext.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height),
            alphaData = alphaContext.getImageData(0,0, alphaCanvas.width, alphaCanvas.height),
            destinationData = destinationContext.getImageData(0,0, destinationCanvas.width, destinationCanvas.height);

        var mergeProperties = $scope.mergeProperties;
        mergeProperties.x = 0;
        mergeProperties.y = 0;
        mergeProperties.offset = 0;
        
        function mergeImages(){

            for(var i = 0; i < mergeProperties.speed; i++){

                destinationData.data[mergeProperties.offset+0]  = sourceData.data[mergeProperties.offset+0];
                destinationData.data[mergeProperties.offset+1]  = sourceData.data[mergeProperties.offset+1];
                destinationData.data[mergeProperties.offset+2]  = sourceData.data[mergeProperties.offset+2];
                destinationData.data[mergeProperties.offset+3]  = 255 -  alphaData.data[mergeProperties.offset+0];

                mergeProperties.x++;
                mergeProperties.offset+=4;
                if (mergeProperties.x >= sourceImg.width){
                    mergeProperties.x = 0;
                    mergeProperties.y++;
                }
                if (mergeProperties.y >= sourceImg.height){
                    destinationContext.putImageData(destinationData,0,0);    
                    return;
                }
            }

            destinationContext.putImageData(destinationData,0,0);    
            $timeout(mergeImages, 10);

        }
        
        mergeImages();
    }

The Timeout code is there just to slow it down for my demo. For actual production you would not have the timeout and the speed. You would just loop until you hit the imageHeight.

So take a look at it, it is pretty cool visualization.
Cheers!