Dataset in React

When life gives you lemons, you make lemonade. And when it doesn’t, hack your way around it. Such was the case with a piece of React code where the previous programmer passed some data-* attributes as props, then onto the JSX markup and later extract them from event.target in the event handlers (or also from the event.currentTarget or from native event). Now, React isn’t ready enough for this (as of January, 2017). The dataset property which are generally accessible via the HTMLElement.dataset property aren’t handled the DOM way.

While playing around wrappers, I had to find a workaround to pass the data-* props. I wrote a little hack to extract the data-* attributes using regex and some spread syntax to pass the dataset to both the outer wrapper, and the inner component.

Example:

render() {
  // Extract the keys present in the `props`
  // Filter the keys which have `data-` as prefix
  // and insert them into `dataset` object
  const dataset = {};
  const { state, props } = this;
  Object.keys(props).filter (value => {
    if (/data-\S+/gi.test(value)) {
       dataset[value] = props[value];
    }
  });
  return (
    <Wrapper {...dataset} onChange={this.handleChange} >
      <Component {...dataset} name="component-type-1">
      </Component>
    </Wrapper>
  )
}

The advantage – you can access the dataset in your handleChange method from the event.currentTarget and event.target. Visit this MDN link to know more about dataset.

Redux forms: Scroll to form field containing error message

  • Redux forms v6.2+ provide you with an onSubmitFail callback when a validation fails in your form.
  • Add refs to all Field elements with name
  • Note: Without refs, this will not work at all.
  • Import the following function as a utility and bind it in your constructor.
  • Whenever there is an error, this scroll the page to the 1st element in the page containing errors.

 


import ReactDOM from 'react-dom';
/**
 * Handles the errors received and determines the first element
 * containing the error as the 'key' element, so that,
 * it's positions can be determined
 * Scrolls the page that element to bring into visibility
 * And focuses on the element
 * Requires developers to use 'ref' attribute with 'name' in form fields
 * @param  {[object]} errors
 * @return {[undefined]}
 */

export function handleSubmitFail(errors) {
    if (!this.refs) {
        return;
    }
    const refsKeys = Object.keys(this.refs);
    const keys = Object.keys(errors);
    let key = null;
    let matchfound = false;

    refsKeys.filter(item => {
        if (keys.indexOf(item) > -1 && !matchfound) {
            key = item;
            matchfound = true;
            return false;
        } else { // eslint-disable-line no-else-return
            return true;
        }
    });

    this.targetNode = this.refs[key];

    if (this.targetNode) {
        const node = ReactDOM.findDOMNode(this.targetNode);
        const parentNode = ReactDOM.findDOMNode(this);
        const xy = node.getBoundingClientRect();
        this.x = xy.right + window.scrollX;
        this.y = xy.top + window.scrollY - 60;
        parentNode && parentNode.scrollTo && parentNode.scrollTo(this.x, this.y) || 
        (parentNode && parentNode.scrollTop && (parentNode.scrollTop = this.y) ) || 
        window && window.scrollTo(this.x, this.y); // eslint-disable-line no-unused-expressions
    }
}

 

Make a Custom Array without distorting the Original

  function MyArray () {
    var _arr = [].slice.call(arguments, 0);
    for( var i=0; i<_arr.length; i++ ) {
      this[i] = _arr[i];
    }
    var THIS = this;
    var max = arguments.length;
    Object.defineProperty(THIS, 'length', {
      enumerable: false,
      get: function() { 
        var keys = Object.keys(this);
        for(var i=0; i< keys.length; i++) {
            keys[i] = parseInt(keys[i], 10);
            if( !isNaN (keys)[i] ){
              if (keys[i] > max) {
              max = keys[i]
            }
          }
        }

        for( var i=0; i<max; i++ ) {
          if( !this[i] ) {
            this[i] = void 0;
          }
        }
        return max;
      },
      set: function(){
        max = arguments[0];
      }
    });


    this.splice = [].splice.bind(this);
    this.push   = [].push.bind(this);
    this.add    = [].push.bind(this);
    this.splice = [].slice.bind(this);
    this.pop    = [].pop.bind(this);

    this.addAll = function() {
      var arr = arguments[0];
      for (var i=0, j = this.length; i<arr.length; i++, j++) {
        this[j] = arr[i];
      }
    };
    return this;
  };


  MyArray.prototype = new Array;
  MyArray.prototype.constructor = MyArray;



  var collection = new MyArray(1, 2, 3, 4);


  console.log(collection);
  //true
  console.log(collection instanceof Array);
  //true
  console.log(collection instanceof MyArray);
  // true

  console.log("collection", collection);
  //[1,2,3,4];
  console.log("collection.length", collection.length);
  //4

  console.log("-------------------------1");


  collection.add("hello");
  console.log("pushed hello");
  //5
  console.log("collection.length", collection.length);
  //5
  console.log("collection[4]", collection[4]);
  //"hello"
  

  console.log("-------------------------2");


  collection.push("world");
  console.log("pushed world");
  console.log("collection.length", collection.length);
  //6
  console.log("collection[5]", collection[5]);
  //world
  console.log("collection", collection);
  //world



  console.log("-------------------------3");


  collection.addAll(["java", "script"]);
  console.log("pushed [java, script]");
  console.log("collection.length", collection.length);
  //8
  console.log("collection", collection);
  //[1,2,3,4,"hello", "world", "java", "script"]


  console.log("-------------------------4");



  collection[8] = "last";
  console.log("assigned collection[8] = 'last'  ");
  //9
  console.log("collection.length", collection.length);
  //9


  console.log("-------------------------5");



  console.log("collection.pop()", collection.pop());
  //"last"
  console.log("collection.length", collection.length);
  //8
  console.log("collection", collection);
  // [1,2,3,4,"hello", "world", "java", "script"]


  console.log("-------------------------6");
  console.log("Array.prototype.addAll", Array.prototype.addAll);
  //undefined


Creating a Guitar Tuner – With modern web APIs

String Frequency Scientific pitch notation
1 (E) 329.63 Hz E4
2 (B) 246.94 Hz B3
3 (G) 196.00 Hz G3
4 (D) 146.83 Hz D3
5 (A) 110.00 Hz A2
6 (E) 82.41 Hz E2

This table can be obtained from the Guitar Tuning wiki page.

So, this is how it goes:

  1. Our objective here is to generate the frequencies when requested, like when a user presses a button
  2. We make use of the Web Audio API to generate the frequencies listed above
    • An extension to it, will be using the micro phone to match the frequencies, but that won’t be covered in this part
    • Paul Lewis has an excellent app built with the above approach
  3. To use the web api, we must create an instance of the AudioContext object
    • Akin to canvas, we must instantiate an audio context object before accessing the web audio api
    • And, to generate the frequencies, we have to create an oscillator.

// create web audio api context
var audioCtx = new (window.AudioContext || window.WebkitAudioContext);

// create Oscillator node
var oscillator = audioCtx.createOscillator();

Now, we’ve to specify the type of wave. These are four natively supported types:

  • sine
  • square
  • sawtooth
  • triangle

A custom type is also available for use. We are not getting into that.

  • We’ll use the sine wave, because that audio wave is bearable.
  • We’ve to set a frequency value at which the oscillator will produce the waves. Let’s set it to E1, i.e. 329.63 Hz
  • We’ve to connect to the destination supported by the Audio Context. The output generally the standard audio interface i.e. your speakers.
  • Next, we start the oscillator.
  • Remember, the oscillator can be started once, and only once. It can be stopped, but can’t be restarted.
  • If you make live changes to the frequency or the type of the wave, the changes are reflected in the oscillator realtime. Hence, the absence of a restart functionality won’t be felt much.

Let’s create an oscillator React component (sorry, p-react, because size matters).

Now, the markup in the snippet ahead appeared gibberish. Therefore, I’ve posted a gist instead.


# oscillator.js
import { h, Component } from 'preact';
import style from './style';

const audioContext = new (window.AudioContext || window.webkitAudioContext);

export default class Oscillator extends Component {

  play() {
    this.oscillator = audioContext.createOscillator();
    this.oscillator.type = this.props.type || 'sine';
    this.oscillator.frequency.value = this.props.frequency || 329.63; //E(1) is default
    this.oscillator.connect(audioContext.destination);  
    this.oscillator.start();
  }

  stop() {
    this.oscillator.stop();
    this.oscillator = null;
  }

  render() {
    return ( /* refer the gist */ );
  }
 }

 

The reasons for creating a new instance every time you hit the start button are

  • The start method only works once per oscillator. Hence, once stopped, there is no way to restart the oscillator.
  • There is no API to suspend and later resume the oscillator.
  • The context can be suspended and resumed later but that doesn’t stop the oscillators. And, when you resume the context after firing multiple oscillators, you hear all of them buzz simultaneously.
  • Therefore, we must create a new oscillator instance then start, every time we hit start and stop-then-destroy the instance every time we hit the stop button.

Now, we’ve to make some buzzing & humming by assigning values to the props. If you can’t see the code here, then follow this gist.

  <Oscillator note="E1" frequency="329.63" type="sine" />
  <Oscillator note="B2" frequency="246.94" type="sine" />
  <Oscillator note="G3" frequency="196.00" type="sine" />
  <Oscillator note="D4" frequency="146.83" type="sine" />
  <Oscillator note="A5" frequency="110.00" type="sine" />
  <Oscillator note="E6" frequency="82.41" type="sine" />

And, we're done.

Caution

Make sure to lower your speaker volumes. If you’re using head phones, then definitely cross check 3 times if your volume is low or not. I don’t want people testing it go all Beethoven on the first day.

Hit the start/stop buttons and tune your guitar along.

Chords

In the similar fashion, we can create a chord component (possibly in the next tutorial) that creates 3 oscillators and plays all of them simultaneously to create a resonating chord.

Hint: A frequency combination for C-major are 196.00 (G), 261.63(C) and 329.63(E). And, for creating a G-major, you can use a combination of 146.83(D), 196.00(G),  and 246.94(B).

happy humming

More

 

webpack sucks, at least for now

Javascript is an interpreted language and by that I understand that when I hit the F5, I expect zero latency for the new script to appear in local dev environment.

When you take that away by introducing obnoxious compilers like webpack – that first needs to be told how to load, then it compiles, then concats before showing me the output, you’re already the subject of my fury.

The ‘wait time’ for compilation sucks

The reasons why I stayed all these years away from coffee script –

  1. I know how to write ‘good’ javascript and
  2. The compilation time – it sucks.

Let JS remain the interpreted language we all know and love. Don’t put your compiled language genius into it. You’re not welcome here – to the interpreted world.

Debugging is horror

you’ve to trace that line out. Imagine a project consisting of 100 small files with almost similar looking content that you concatenated and now clueless where exactly to hunt and debug.

It’s not uncommon – when you write derived components inherited from parent components, the siblings tend to look similar.

webpack – you’re a clutter builder and clarity killer. And, No. I’m not going to work in large files a.k.a monoliths just to support your existence.

Lack of build blocks

I came from an AngularJS Development environment, where I extensively used yeoman and that allows me to work on an index.html file locally which has references to locally kept css and JS.

That means we don’t have to wait for concat or compile before we hit the F5 or ctrl+r.

Plus, the library files from bower_components stay separate. In webpack, unfortunately, they become part of the compilation step.

Luckily, we’ve wiredep and usemin blocks for our rescue – which simplifies local development and gives great support for production builds.

Learn something from it. Your hotness may look tempting to fools and noobs. I ain’t one. Grow up.

Till then – happy hating.

Remedy

And, I always believe there is no point in complaining, one must find a remedy. Following are some workarounds to reduce frustration:

The little catch(es) with Arrow Functions inside Accessors and Methods

Arrow functions are shorthand notation for function expressions. Although the catch is with the binding of this keyword in the context of accessors

Follow the code snippet below:

'use strict';
var obj = {
  a: 10
};

//Snippet A:
Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this);
    return this.a+10; // represents global object 'Window'
  }
});

//Snippet B:
Object.defineProperty(obj, "b", {
  get: function() {
    console.log(this.a, typeof this.a, this);
    return this.a+10; // represents current object 'obj'
  }
});

Though the snippets A & B may appear to be working alike, the only catch is with this binding, in the snippet A, where the arrow functions doesn’t bind the this keyword as expected.

I’m a little puzzled, not sure if it’s a bug or a feature, because MDN mentions:

An arrow function does not create it’s own this context, rather it captures the this value of the enclosing context

 

The binding of lexical this takes place differently in case of Arrow functions.

Examples below:

'use strict';
var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b(); // prints undefined, Window
obj.c(); // prints 10, Object {...}

Common Assumption: this.i should behave like any other function inside. NO.

 

Another example involving call (yanked from MDN):

var obj = { base: 1 };
var f = v => console.log(v + this.base, this);
var g = function ( v ) { console.log(v + this.base, this); };
f.call(obj, 2); // logs NaN, Windows
g.call(obj, 2); // logs 3, Object { base... }  

 

The anomaly in the aforementioned snippet ‘A’ is an ‘expected behavior in ES6’ albeit not anticipated in ES5.

Therefore, it can be safely concluded that arrow functions  can well be used for functions, but they are not ideal candidates for Methods. And, as MDN quotes:

Arrow function expression are best suited for non-method function

 

Bonus: Here is a little mindfuck to play around. Try to guess the output.
(() => ({ foo: () => ({ foo: () => ({ foo: () => ({ foo: () => ({ }) }) }) }) }))();

What? It was easy? Nice. Try the next
(() => () => () => () => () => ({}) )()()()()();

Pacman much?
(() => () => () => () => () => {})()()()()();

Update: Updated the same code as examples in MDN

http2, https and more

Before we begin anything, let these information sink in. Watch the following video:

URL: www.heavybit.com

Long back when I was serving an eCommerce major, our team evaluated HTTP2 over http and it was concluded that the gains were minimal. TBH, I felt our premise was wrong, our approach for evaluating http2 was unduly done (read ahead to know). It was later concluded that we were not going for http2 because it had low ROI.

Right now, in my current org., I tried to push through http2 along with https (https because of the reasons mentioned ahead). My proposal wasn’t accepted, again because of Low ROI.

There are several costs associated with going with http2 + https viz

  • Investing on procuring an SSL certificate
  • Evaluating nginx 1.9.5
  • Reading through the documentation and setting up the nginx.conf
  • Troubleshooting on staging / prod environments
  • Change in build script to optimize the outputs for http2 protocol
  • Despite being least of our concern, lack of support in legacy browsers is kind of inhibiting if your priority is to get everyone onboard.
  • Another small concern is over 3rd party tools – all web apps use premium (not free) 3rd party tools to study user behavior. Checking their compatibility with https is important again. (Small concern – because most 3rd party tools realize this & they serve their contents from https. But there could be smaller players who do not have this capability).
  • Change of origin – A change in protocol i.e. from http to https will change the port from :80 to :443. This alters the URI schema. Hence, it’d also imply that the origins have changed. Although, I’ve not validated this or the areas of impact, but it impacts the current SEO or anything else, it’ll be a bigger concern to us than anything else
  • Non-secure content – We load our static assets from CDNs and thankfully, Amazon cloudfront supports both http and https. But, if any of our providers failed to provide us with an https endpoint, we’ll be hopeless

Reason for going with https:

  1. The idiosyncrasies associated with proxy servers and anti virus software to sniff unencrypted http1.1 content. And, if they spot any anomaly in headers e.g. the http version, they’ll simply flag the content as malicious
  2. Google Chrome is anyway going to shame non-https websites
  3. https has elevated priority in SEO ranking over non-https. At least, Google obeys this and as a JS-dynamic-template-heavy website, my sole hope for SEO is Google’s Page Rank algorithm alone.

What went wrong with our previous http2 evaluation

http2 is not just the version digit incremented. The transition of the version no. indicates that the new version is a total paradigm shift from the earlier version. http2 protocol works better on small splitted files – hence, our age-old practice of concat-minify-obfuscate-revv won’t work.

Key takeaway 1:

To get the best out of http2, you need many small files minified-obfuscated-revved, not concatenated into single file.

Check these link to get a better idea on the goodness of many small files:

Bonus tip: For a cherry on top the cake, you can further use AMD to load modules whenever needed.

Our last evaluations were based on testing speeds with single-large files. Hence, the gains looked minimal. HTTP2 wasn’t designed perform better with large files.

Key takeaway 2:

Domain sharding is no longer a requirement.

To parallelize static asset loading, we heavily depended on domain sharding i.e. splitting resource requests across multiple domains thereby opening multiple TCP connections.

http2 doesn’t require that. Multiple static resources should be requested over one and only one TCP connection. Unfortunately, this was not how we evaluated.

Key takeaway 3:

Encrypted connection i.e. https is not slow. Google’s SPDY protocol, which could be enabled by just enabling another flag, was the best way for loading resources https, until http2 came in.

It had to be good enough for Google to declare its annihilation/ further usage & support.

What to do next to convince your team to go for http2 + https

Every decision in an organization should be based on facts, based on data a.k.a. Data driven decisions. Decisions can’t be made on the basis of popular remarks/opinions. So

  • Gather data about https adoption across industry
    • gather all benchmarking studies and results
    • gather its success stories
    • perform your perf tests on your existing system and gather benchmarking data
    • analyze performance data from http2 & utilize this data to show comparisons
      • e.g. if your new server gives a time boost of even a thousand milisconds, that’s a major save
    • PS: performance tests can be baffling and overwhelming. One feels as if they’re part of some Formular 1 team doing performance improvements
  • Clearly explain the need of encryption and how encryption leads to greater trust and security
  • Make everyone understand that SSL certificates are no longer hard-to-obtain
    • Companies like startssl can offer you a free ssl certificate to get started with
    • Additionally, your bash console comes powered with openssl tools. You can leverage it to create a self-signed certificate for your dev environments
  • Start your POC
    • fork your repo, create an experimental branch
    • Perform benchmarking tests
    • and, do an A/B test
    • Check the conversion rates on each system

I’m using Node.JS / Apache. How can I go for http2?

At the time of writing this article, I’ve n’t explored about Node.JS support for http2. There could be libraries to help you out with this. Or may be, Node inherently support http2 out of the box. I do not know yet. (will update this post when I figure it out). Same applies to Apache as well.

However, nginx 1.9.5 has http2 enabled. Therefore, you can always put an nginx proxy in front of your current server – be it node.js or apache, or any server.

  • Setup nginx 1.9.5 on your box
  • Specify http2 with ssl along with http
  • Upload your certificates & configure the server correctly
  • Run your nodejs server on a different (system unreserved) port (you can block this port from public access too)
  • Configure the nginx proxy to consume data from nodejs server

This will ensure that nginx (which is well maintained and free and also supports the required http2 + https setup) will take charge of encrypting & http2-fying your site while your nodejs app keeps working the way it has always been.

Grow up bozo!

Everyday I meet programmers who have cleared tough programming rounds. We made them write tough algorithms – starting from inverting a binary tree to dynamic programming. Some of them were so ahead of their contemporary peers that they’d evaluated all of the existing frameworks.

However, to my utter surprise, when it comes to working, their everyday thought process seems to have diverged tangentially since the day we hired them.

We ask you data structures, that too in an interview to understand if you follow the best practices under pressure, so that if a day comes when we run into a production bug prioritised P1, and ETA in few more hours, we expect you to deliver it with as sincerely as you wrote that binary tree on the day of interview.

Screen Shot 2016-01-23 at 3.14.21 pm

(the image above is unrelated to the rant, but shows how deep recursion can go upto)

 

Reason behind this rant:

One day, at work, I came across a piece of code written by an abler colleague – it was a JSON parser, that constructs a tree view out a deeply nested JSON tree.

  1. When you see a nested structure like that, the immediate structure that’d come to mind will be either a graph or a tree, or at least a linked-list. You don’t recurse dammit.
  2. You intended to write a lot of if-else‘s – If those if-else blocks give you orgasms,  then make sure you narrate the experience in some documentation or even comments, so that a reader gets an idea how shitty your sexual ideas are
  3. No Unit testing
    • Why people have a feeling that they’re doing the universe a favour by writing proper descriptive unit tests?
    • Why your unit tests always look like cliched movie one liners
      • forEach(testCase in AllTestCases) {
          assert( testCase.mockedService( testCase.SampleInputJSONObject ), testCase.expectedOutPutObject ) );
        }
        
    • Why your commit messages look like snarky remarks on movie trailers
      • "Fixed this because some shit was happening in XYZ module"
      • Really? That some shit was highly insightful, thank you.
    • Why I’m able you judge your upbringing from the manner you practice software engineering?
    • If you write that kind of commit messages, those kinds recursive code, clearly, I will judge you 100 times before writing a line of code

 

Honestly – your tiny shit ( or call it piece of code) is not worth of that debugging effort. But, regressions – they’re painful, and even more painful when you’ve written a useless unit test.

AngularJS: Scroll into View after $digest

I was using jQuery with AngularJS in one of my projects and there was a requirement to fetch some contents & I had to scroll the content to visible area upon their arrival.

The general approach to fetch content is a promise, and we can update the contents to scope in the success callback.

SomePromiseObject
.then(function( contents ) {
  $scope.contents = contents;
  $scope.loading = false;
  var value = $("#section").offset().top - $("#section").height();
  $("body").stop().animate({
    scrollTop: value
  }, 500);
});

But the issue arises while determining the offset position. We measure the offset synchronously and by that time, the $digest() hasn’t finished & hence, there is no content in the section.

In such a case, we can either defer the call using a setTimeout or $timeout and observe the $$phase.

But, what could save us from some frustration is actually – a callback function, after $digest() has finished.

Finally, I found a solution to this in git-issue comment-33020323, as mentioned in this SO answer.

And, it worked!!!

SomePromiseObject
.then(function( contents ) {
  $scope.contents = contents;
  $scope.loading = false;
  $scope.$$postDigest( function() {
    var value = $("#section").offset().top - $("#section").height();
    $("body").stop().animate({
      scrollTop: value
    }, 500);
  });
});

Sublime Text Plugins and Snippets worth exploring – For the modern day

Monokai Neue

Install this first and proceed because a feature has been really missing in sublime.

I use Sublime text 2 and so far it has been my most favourite text editor. My love for it increases with more features I find. Here is a small collection of my favourite set of plugins and snippets and I hope you’ll love them too.

dedicated to all ‘serious front end developers’

Pro tip: For permanently setting a particular syntax highlighting go for View -> Syntax -> Open all with current extension as... ->[your syntax choice]
Compare Side-By-Side

For comparing 2 files, sublime has a built-in file comparison mechanism. Right click on the tab to find ‘compare with…’  option.

Nevertheless, a text comparison tool is definitely a handier alternative and this plugin brings it inside sublime-text.

AngularZen

Sublime text snippets for angularjs developers.

Javascript Beautify

Isn’t it convenient to have such a utility inside the editor. There are some related plugins that you can also hunt for – json formatter, json highlighter, json /xml prettifier etc.

Babel

If you’re working with ES6 too early, then you may like this. This has syntax definitions for ES6 JavaScript with React JSX extensions. You may like Babel Snippets too.

Jasmine Scaffold

This one makes writing your specs breeze. Just write your specs in plain english, indented properly (for describe & it blocks) & hit Ctrl (Win-Alt) (Mac-Cmd) Shift + J.

If you liked that, then you may also find UnitJS even more fun.

Underscorejs snippets

As the name implies, it helps you generate snippets for underscore, a similar package exists for lodash called Vanilla lodash Snippets

Sublime Linter

It requires you to have jscs installed in your machine and a path to a linter executable. A live linter is indeed a necessity in case of an interpreted language like javascript. Not just it saves you from errors, it keeps your code neat if you’ve linters check enabled in your git hooks.

There are some more packages that I’ve not explored yet, but will love to, and they are

Convenience

Dot files Syntax Highlighter

Want ShellScript (Bash) syntax highlighting for your dot files? You’re damn right you do! This plugin is a must for all kinds of developments because you can never get past dot files.

Slugify

Often times you would have desired to slug selected portion of text, this saves your mind

JsRun

A blissful creation from sindresorhus – just select your snippet in sublime, then in the command pallete hit “Run JavaScript in the browser”. Further, you can connect your choice of browser. That’s superb for lazy coders like me.

Focus

When you’re working with your content provider, tweaking minor texts in the static html files, and when text is all that matters to you, then you will love this – another nifty solution from  sindresorhus. This will totally save your day.

Syntax Highlighting for Sass

Its also available for atom & text-mate.

See also: How to exclude Folders from Sublime Text Search

Snippets

Sublime text snippets the most loveable feature I’ve ever found. There are plenty out there, to simplify your daily coding activity. You can write your own code snippets too. There is a decent article on Hongkiat on this too. Here are some snippets that will drive you crazy.

Pro Tip: Make it a habit of routinely invoking the Package Controller, cmd/ctrl + shift + p and typing ‘ip‘. This will highlight the Package Installer. Then, you can search for your beloved set of keywords e.g. Emmet, React, Snippets, JS, json, es6, babel, node etc. and hit enter after selection

Comment Snippets

My most favourite snippet, this makes writing documentation headers smooth. It feels like magic. I fell in love with it in the first sight.

React Snippets

The next generation of snippets i.e. in ES6 for programming with React. Just type React.component and it autocompletes with a code snippet with cursors at the right locations to name your component.

JavaScript and NodeJS Snippets

cd, ce, cl, ae and tons of many other shortcuts to autocomplete your code – if you code in JS everyday, you’ll simply fall in love with it.

Jasmine Snippets

If you liked the Jasmine Scaffold plugin mentioned above, you may also like the jasmine snippets. Unlike the plugin, it’s just quick text to help you with the petty stuff.

Angular Material Snippets

Generates Angular Material snippets for , , as directives referred in the documentation.