Can modern browsers run TypeScript code, without compiling?

Recently, I bumped into this interesting question as part of a discussion with a fellow developer. As a developer who uses TypeScript often (as part of creating various Angular projects), I was curious to understand what would happen if you try to run raw TypeScript code, such as the one below, directly in your browser without compiling (e.g. by putting it inside the <head> tag).

const sum = (a:number, b:number)=>a+b;
sum();

Go ahead… try it.


If you try to execute it, you will likely encounter the same error as I did:

Uncaught SyntaxError: Unexpected token ':'

The reason for this is because all modern browsers follow the ECMAScript scripting-language specification, the same way that TypeScript follows it. However, they both follow it a different “pace”. Currently, TypeScript adopted features from far more modern versions of ECMAScript, whereas browsers like Google Chrome or Mozilla Firefox have barely adopted support for ECMAScript 2015 and partial support for ECMAScript 2016.

As a result, several features that are available in TypeScript are still not available in IE or Firefox due to their slower release cycle and slower adoption of ES in general.

How do I run TypeScript code inside the browser then?

Short answer, you can’t. You need to compile the .ts code into plain .js that is understood by all browsers and browser versions (e.g. IE6). You should acknowledge the fact that probably not all of your end users have the latest version of any given browser.

The good news is, that the framework that you are using (e.g. Angular, React) probably already has a good compiler that does the heavy lifting for you (e.g. Babel). A compiler’s job is to take the “modern” TypeScript that you write and convert it into “old school” .js files that work across all browsers and browser versions (optionally, including some polyfills),

A compiler may also create the so-called “.js.map files” that represent the links/relationship between the compiled .js code and the original .ts source code, allowing for easier debugging and breakpoint usage.

Why VueJS lost me on the first day I tried it?

VueJS is a great micro frontend framework for building single-page applications. However, one serious limitation struck me today, that will probably stop me from using the framework for any serious project from now on.

Specificifically, the fact that you can not use arrow functions (ES syntax) if you declare a VueJS method that reads or writes to one of the Component’s data properties (a very common scenario).

For example, let’s imagine you have a component that does 2 things: it has a form with a single text input and a button to trigger a search based on the text input value (think of it like the Google homepage). The value of the text input is usually stored as a data property within the component, through model binding (v-model="attribute-name-here"). As you press the button, you trigger a method within the component that is supposed to “read” that attribute and make an API call (e.g. using the axios library) and pass that value to the API. The API responds with some values that you may also want to map as data attributes of the component. Both of these things – you can not do, if you use the arrow syntax for the method.

The reason is – arrow syntax changes the this context and it no longer refers to the Vue component itself. This effectively means that the following example is not possible:

    export default {
        name: 'HelloWorld',
        data: () => ({
            url: '',
        }),
        methods: {
            someMethod: () => {
                // Make an API call to retrieve some data by using a component data attribute
                axios
                    .post('http://0.0.0.0:8081/api/link', {
                        // Try to get a component data variable
                        // This results in a "trying to get a property of undefined" error
                        // because "this" doesn't refer to the HelloWorld component
                        url: this.url
                    })
                    .then(() => {
                        // Do something with the response
                    });
            }
        }
    }

The solution is simple – replace the someMethod definition from an arrow function to a regular function(){}. This doesn’t really make sense in the modern frontend development age though and is not something for Vue to enforce. Arrow functions are the future and I shouldn’t be forced to use a mixture of ES and non-ES syntax, just because I rely on some framework (VueJS).

You can read more about the reasoning why this happens in the Vue documentation. Here’s an excerpt:

Don’t use arrow functions on an options property or callback, such as created: () => console.log(this.a) or vm.$watch(‘a’, newValue => this.myMethod()). Since an arrow function doesn’t have a this, this will be treated as any other variable and lexically looked up through parent scopes until found, often resulting in errors such as Uncaught TypeError: Cannot read property of undefined or Uncaught TypeError: this.myMethod is not a function.

https://vuejs.org/v2/guide/instance.html#Instance-Lifecycle-Hooks

What’s your thought on that? Have you bumped into the same limitation? Is there an easy workaround or you just “get along” and consider this an acceptable thing?

Automatically close Angular Material Sidenav when menu element is clicked

I’ve recently started digging deeper into Angular Material – the UI kit by Google to be used in Angular projects.

The stack of components available is pretty rich and flexible and includes a variety of things that you can use to quickly scaffold an application, including a Toolbar, Menu, Sidenav, etc.

One thing that I discovered that doesn’t come out of the box is the ability to automatically hide the Sidenav (left side menu) when you click on some of the menu items. Here’s an example structure that I had for a recent project:

The left side is the <mat-sidenav> component and the right side (the table) is wrapped in a <mat-sidenav-content> component. Both of them are wrapped in a <mat-sidenav-container> component.

I wanted to automatically hide the sidebar whenever any of the menu elements: Homepage, Transactions, Accounts, My profile – is being clicked. The solution was pretty simple actually:

<mat-sidenav-container class="example-container">
  <mat-sidenav #sidenav (click)="sidenav.toggle()">
    // My menu is here
  </mat-sidenav>
  <mat-sidenav-content>
    // My main content is here
  </mat-sidenav-content>
</mat-sidenav-container>

The trick is to call sidenav.toggle() when a click is triggered on the <mat-sidenav> component.

Angular pipe for displaying a timestamp in a human-friendly way

Angular is a great framework that comes with a variety of good things such as “routing”, “cli” and some good built-in Pipes to get you started. Although those are enough to get your project off the ground, often times you’ll encounter scenarios where you’ll have to get your hands dirty and plug your custom use cases on top of what the Angular framework provides.

One such use case I had recently, while working on the audiobooks portal Audiobooke.com, was the ability to take a raw timestamp of seconds from the database and visualize it inside an Angular component’s template, in a “human friendly” way (in other words display a value of “60” as “1 minute” or 3665 as “1 hour 1 minute 5 seconds”, etc).

Here are the steps I did to create a custom Angular pipe to visualize timestamps in a human friendly format:

Install the dependency that does the heavy lifting

npm install --save pretty-ms

This will install a library that does a pretty good job of transforming timestamps to human-friendly labels in vanilla JavaScript. No need to reinvent the wheel here.

Create a custom pipe

Now we create a new Angular pipe that we can reuse inside templates.

import {Pipe, PipeTransform} from '@angular/core';
import * as prettyMs from 'pretty-ms';

@Pipe({
  name: 'secondsHumanFriendly',
})
export class HumanFriendlySecondsPipe implements PipeTransform {

  transform(seconds: any) {
    return prettyMs(seconds * 1000);
  }
}

Import the pipe into your AppModule

We are assuming that your app consists of just one NgModule. This is rarely true for a production app, so make sure to include the pipe into the correct module where it will be needed. Note that if you want to reuse the Pipe into multiple modules at once, you need to wrap it into its own NgModule and import the new NgModule instead. The example below illustrates exactly this “production ready” use case.

// human-friendly-seconds.module.ts

@NgModule({
  declarations: [
    HumanFriendlySecondsPipe
  ],
  providers: [],
  exports: [
    HumanFriendlySecondsPipe
  ]
})

export class HumanFriendlySecondsModule {

}
// app.module.ts
@NgModule({
  declarations: [
    // Your real components go here
    AppComponent,
  ],
  imports: [
    // We include the above HumanFriendlySecondsModule module
    // as a reusable dependency here, so we can take advantage of its
    // exported Pipes
    HumanFriendlySecondsModule,
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

Examples

Let’s give our code a test drive. Go into the template of your AppComponent or whichever component you want to visualize a timestamp in. Inside it’s template, we try the following examples:

{{60 | secondsHumanFriendly}}<br/>
{{3600 | secondsHumanFriendly}}<br/>
{{3663 | secondsHumanFriendly}}<br/>
{{999999 | secondsHumanFriendly}}<br/>

The results are:

1m
1h
1h 1m 3s
11d 13h 46m 39s

Happy coding!

Angular 4.0.0-rc.6 released

Angular 4 Release Candidate 6 has just been released today (23 March 2017). The list of features and bugs fixed can be seen in the changelog, but the most important fixes are in the areas of the animations and small fixes to the compiler. No significant or backward incompatible changes are introduces compared to Angular 4.0.0-rc.5.

Download Angular 4.0.0-rc.6

Here’s the full changelog:

Creating a simple Angular 2 CRUD app, based on the MEAN stack

Angular2, Node.JS, Express and Mongo – one of the preferred stacks for fresh developers and experienced ones. Being a full-fledged solution that covers the frontend, server-side and database storage of things, the MEAN stack is an easy way to get going with any small to medium sized project.

In this tutorial, you’ll see how to create a simple Angular2 based frontend application for managing your book collection in a list based manner, taking advantage of variety of technologies offered by Google’s library like – services, components and the Angular2 routing.

The backend will be powered by the NodeJS technology, which has the all-familiar JS syntax. But don’t be confused by the fact that JS is mostly a frontend development language. In this example, NodeJS empowers one of its popular frameworks for serving a backend web server – Express.

All data persistance happens in a MongoDB database (stored locally, but can also be connected to a remote production/development server). MongoDB is a popular NoSQL storage engine that is good for storing big chunks of non relational data.

The stack also contains the standard CRUD operations – add, edit, delete a book. It’s the perfect example for starting a real world Angular2 based application.

Read the tutorial