Category Archives: JavaScript

Reactive Extensions (Rx) in JavaScript (rxjs)

Reactive Extensions are everywhere – I wanted to try the JavaScript version of the library, so below is a sample React component demonstrating a “fake” service call that might occur within the fetch function. The setTimeout is used simply to simulate some latency in the call.

To add rxjs simple use

yarn add rxjs

Now here’s the sample component code…

import {Observable, Subscriber, Subscription} from 'rxjs';

interface ServiceState {
  data: string;
}

class ServiceComponent extends Component<{}, ServiceState> {

  _subscription!: Subscription;

  constructor(prop: any) {
    super(prop);
    this.state = {
      data : "Busy"
    };
  }

  fetch() : Observable<string> {
    return Observable.create((o: Observer<string>) => {
      setTimeout(() => {
        o.next('Some data');
        o.complete();
      }, 3000);
    });
  }

  componentDidMount() {
    this._subscription = this.fetch().subscribe(s => {
      this.setState({data: s})
    });
  }

  componentWillUnmount() {
    if(this._subscription) {
      this._subscription.unsubscribe();
    }
  }  

  render() {
    return (
      <div>{this.state.data}</div>
    );
  }
}

In this example we have the fetch function returns an instance of an Observable of type string. We then subscribe to this within the componentDidMount function, which is called when the component is inserted into the DOM and then we subscribe to the Observable, updates will be applied to the component’s state.

The componentWillUnmount is called when the component is removed from the DOM and hence we unsubscribe from the Observable.

Starting out with web components

Introduction

Web components are analogous to self-contained controls or components as you’ll have seen in Windows Forms, WPF etc. They allow developers to package up style, scripts and HTML into a single file which also is used to create a custom element, i.e. not part of the standard HTML.

Sadly, still not yet available in all browsers (although I believe Polyfills exist for the main ones). Hence, for this post you’ll either need a polyfill or the latest version of Google Chrome (which I’m using to test this with).

What does it look like using web components?

To start with we create an HTML file for our web component, we then define the template for the component – this is basically the combination of style and the control’s HTML. Finally we write scripts to effect the shadow DOM by interacting with our web component.

In this post we’re going to create a simple little web component which will flash it’s text. Before we look at the component code let’s see the component in use within the following index.html file

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Web Component Test</title>
    <link rel="import" href="flashtext.html">
</head>
<body>
   <flash-text data-text="Hello World"></flash-text>
</body>
</html>

The key points here are that we include the web component using the line

<link rel="import" href="flashtext.html">

and then we use the custom element flash-text with it’s custom attributes and we use the component like this

<flash-text data-text="Hello World"></flash-text>

It’s important to note the closing element, a self closing element is not correctly handled (at least at this time using Google Chrome) and whilst the first usage of a web component might be displayed, if we had several flashing text components in the index.html it’s possible only one would be displayed and no obvious error or reason for the other components not displaying.

Creating our web component

We already decided our component will be stored in flashtext.html (as that’s what we linked to in the previous section).

To start off with, create the following

<template id="flashTextComponent">
</template>
<script>
</script>

We’ve created a new template with the id flashTextComponent. This id will be used within our script, it’s not what the pages using the component uses. To create a new custom element by adding the following to the script

var flashText = document.registerElement('flash-text', {
});

But we’re getting a little ahead of ourselves. Let’s instead create some styling and the HTML for our component. Within the template element, place the following

<style>
   .flashText {
      float: left;
      width: 152px;
      background-color: red;
      margin-bottom: 20px;
   }

   .flashText > .text {
      color: #fff;
      font-size: 15px;
      width: 150px;
      text-align: center;
   }

</style>
<div class="flashText">
   <div class="text"></div>
</div>

The style section simply defines the CSS for both the flashText div and the text div within it. The div elements create our layout template. Obviously if you created something like a menu component, the HTML for this would go here with custom attributes which we’ll define next, mapping to the template HTML.

Next up we need to create the code and custom attributes to map the data to our template. Before we do this let’s make sure the browser supports web components by writing

var template = document.createElement('template');
if('content' in template) {
   // supports web components
}
else {
   // does not support web components
}

If no content exists on the template, Google Chrome will report the error in the dev tools stating content is null (or similar wording).

Within the // supports web components section place the following

var ownerDocument = document.currentScript.ownerDocument;
var component = ownerDocument.querySelector('#flashTextComponent');

var templatePrototype = Object.create(HTMLElement.prototype);

templatePrototype.createdCallback = function () {
   var root = this.createShadowRoot();
   root.appendChild(document.importNode(component.content, true));

   var name = root.querySelector('.text');
   name.textContent = this.getAttribute('data-text');

   setInterval(function(){
      name.style.visibility = (name.style.visibility == 'hidden' ? '' : 'hidden');
   }, 1000);
};

var flashText = document.registerElement('flash-text', {
    prototype: templatePrototype
});

Let’s look at what we’ve done here. First we get at the ownerDocument and then locate our template via it’s id flashTextComponent. Now were going to create an HTMLElement prototype which will (in essence) replace our usage of the web component. When the HTMLElement is created we interact with the shadow DOM placing our component HTML into it and then interacting with parts of the template HTML, i.e. in this case placing data from the data-text custom attribute, into the text content of the div text.

As we want this text to flash we implement the script for this and attached to the visibility style of the text.

Finally, as mentioned previously, we register our custom element and “map” it to the previously created prototype.

Using in ASP.NET

ASP.NET can handle static pages easily enough, we just need to add the following to the RouteConfig

routes.IgnoreRoute("{filename}.html");

Now, inside _Layout.cshtml put in the head section

and within the Index.cshtml (or wherever you want it) place your custom elements, i.e.

<flash-text data-text="Hello World"></flash-text>

References

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
https://developers.google.com/web/fundamentals/web-components/customelements
https://www.webcomponents.org/
https://stackoverflow.com/questions/45418556/whats-the-reason-behind-not-allowing-self-closing-tag-in-custom-element-in-spec

Code for this post

https://github.com/putridparrot/blog-projects/tree/master/webcomponent

Promises in JavaScript/TypeScript

Promises, are analogous to futures or tasks (if you background is C#) and are used for asynchronous code.

I’m using TypeScript at the moment (as part of learning Angular 2) but I’ll try to list code etc. in both JavaScript and TypeScript, solely to demonstrate the syntax. The underlying functionality will be exactly the same as (of course) TypeScript transpiles to JavaScript anyway.

The syntax for a promise in JavaScript looks like this

let promise = new Promise((resolve, reject) {
   // carry out some async task
   // then resolve or reject
   // i.e. resolve(result);
   // and/or reject("Failed");
});

As you can see in the above code, we can (in essence) return a success, with resolve or a failure, with reject.

In some situations we might simply wish to immediately resolve or reject without actually executing any asynchronous code.

In such situations we can use the methods Promises.resolve and/or Promise.reject method calls, i.e.

// in JavaScript
function getData() {
   return Promise.resolve(data);
   // or 
   return Promise.reject("Cannot connect");
}

// in TypeScript
getData(): Promise<MyDataType> {
   return Promise.resolve(data);
   // or
   return Promise.reject("Connot connect);
}

As you can see the difference between TypeScript and JavaScript (as one might expect) is the strong type checking/expectations.

Using the results from a Promise

As a promise is potentially going to be taking some time to complete we need a way to handle continuations, i.e. what happens when it completes.

In C# with have ContinueWith, in JavaScript we have then, hence our code having received a Promise might look like this

let promise = getData();

promise.then(result => {
   // do something with the result
}).catch(reason => {
   // failure, so something with failure
});

There are other Promise methods, see promise in JavaScript but this should get us up and running with the basics.

JavaScript – Encapsulation

In JavaScript everything is an object from the obvious, such as arrays, strings etc. through to functions.

So how do we handle encapsulation such that we will have private and public data and methods ?

Well, because functions are themselves objects we can declare private data internally (within the function) and then using the prototype property we can add methods to the function that are public.

Below is a very simple example of encapsulation. The variable balance is private as it’s declared within the scope of the BankAccount function.

function BankAccount() {
   var balance = 0;

   BankAccount.prototype.add = function(amount) {
      balance += amount;
   }

   BankAccount.prototype.subtract = function(amount) {
      balance -= amount;
   }

   BankAccount.prototype.getBalance = function() {
      return balance;
   }
};

The functions add, subtract and getBalance are public and thus we can interact with this object using the following

var bankAccount = new BankAccount();
bankAccount.add(100);
bankAccount.subtract(10);

var current = bankAccount.getBalance();

If we wanted to make the balance variable public, we could simply alter the var balance = 0 to this.balance = 0 but of course this allows us to change the balance variable without going through the add/subtract methods.

To implement a more property like variable (as per C# for example) whereby we have methods to get/set the property we might look to implement something like

function BankAccount() {
   var balance = 0;

   this.__defineSetter__("balance", function(x) {});
   this.__defineGetter__("balance", function() { return balance; });
   
   // rest of the methods as before
};

Here we define a getter such that we can access in this way bankAccount.balance but we’ve defined a setter that does nothing so whilst a setter exists it doesn’t alter the balance.

JavaScript Refresher – Properties, Methods and Types

Properties and Methods

JavaScript is a dynamic language. We do not need to declare properties or methods on an object prior to using them, for example the following will automatically add a new property and method to an object

var o = new Object();
o.Message = "Clicked";
o.Clicked = function() {
   alert(this.Message);
}

So in the above code we create an instance of an Object and then by calling o.Message we basically add a new property to the object o. Next we create a method on the object. Note: We need to use “this” to access the property from within the method otherwise the code tries to access an undefined variable.

We can actually add properties and methods as well as access them using indexer notation, for example

var o = new Object();
o["Message"] = "Hello";

and this allows us to even call methods dynamically such as

var clicked = "Clicked";

var o = new Object();
   o["Message"] = "Clicked";
   o["Clicked"] = function() {
      alert(this["Message"]);
   }


   o[clicked]();

So in the above we can dynamically change the method called (assuming we had more than one method).

We can also iterate over the members of an object using the following

var o = new Object();
   o["Message"] = "Clicked";
   o["Clicked"] = function() {
      var s = "";
      // iterate over the object
      for(var p in o)
      {
         s = s + p + ";"
      }
      alert(s);
   }

Using the for..in loop we simply iterate over and object, the string “s” will be “Message;Clicked”.

Finally, we can add properties and methods, but we can also delete them using

delete o.Message;

This deletes the Message property from the object o.

Types

JavaScript is loosely types. We declare variables using the var keyword and a variable can change type at any time, for example

var tmp = 3.1415926;
tmp = "Hello";

The runtime will not complain about the type conversion from a floating point number to a string.

JavaScript has a small number of types which include, string, number, boolean, array and object.

  • A string may be declared using either double quotes or single quotes, obviously this helps when the string is declare inline.
  • A number can be declared with or without decimal places (in other words it can be floating point or an integer).
  • A boolean may be true or false (as one would expect)
  • An array can be declared in various ways (described later) and can store heterogeneous data types
  • An object can be declared and properties and methods assigned to it (see above)

If a var is not assigned a value it is “undefined” (which is itself a type), basically this is a variable that has no value, but we can also use null to denote an “empty” value.

Declaring Arrays

Arrays can be declared in various ways, for the first example we declare an array and then we dynamically add items by creating an index to them

var vowels = new Array();
vowels[0] = "a";
vowels[1] = "e";
vowels[2] = "i";
vowels[3] = "o";
vowels[4] = "u";

A couple of alternatives are

var vowels1 = new Array("a", "e", "i", "o", "u");
var vowels2 = ["a", "e", "i", "o", "u"];

JavaScript Refresher – Using JavaScript in HTML

How to use JavaScript in an HTML file

JavaScript is a dynamic loosely typed language which is now the lingua franca of the browser now.

We can add JavaScript to a web page as inline, embedded or in an external .js file. For example

Inline

<input type="button" value="Click Me!" onClick="alert('Clicked');" />

In the above the inline JavaScript will display an alter in response to the button being clicked.

Embedded

The same code as above but with the JavaScript embedded would look more like

<script>
function clicked() {
   alert('Clicked');
}
</script>

<input type="button" value="Click Me!" onClick="clicked();" />

I’ve removed superfluous code but the usual place to put the script is in the section.

External File

If we have a file name (for example) scripts.js then we’d place the scripting code in that file as below

function clicked() {
   alert('Clicked');
}

and in the of the HTML file we’d have the reference to the script

<script type="text/javascript" language="javascript" src="scripts.js"></script>