Categories
JavaScript Rxjs

More Rxjs Transformation Operators — Window

RxJS is a library for reactive programming. Creating operators are useful for generating data from various data sources to be subscribed to by Observers.

In this article, we’ll look at some window operators, including the windowCount, windowTime, windowToggle and windowWhen operators.

windowCount

The windowCount operator branch out the source Observable values as a nested Observable with each of them emitting at most windowSize events.

It takes up to 2 arguments. The first argument is the windowSize, which the maximum number of values to be emitted by each window.

The second argument is optional. It’s the startWindowEvery number, which defaults to 0. It’s the interval to start a new window. The interval is measured by the number of items emitted by the source Observable.

For example, we can use it as follows:

import { interval } from "rxjs";  
import { windowCount, mergeAll, take, map, skip } from "rxjs/operators";
const nums = interval(1000).pipe(take(1000));  
const result = nums.pipe(  
  windowCount(3, 3),  
  map(win => win.pipe(skip(1))),  
  mergeAll()  
);  
result.subscribe(x => console.log(x));

The code above has the nums Observable which emits a number every second up to 1000.

That’s pipe d to the windowCount operator which emits 3 values at a time and starts a new window after 3 values emitted from nums .

Then that is map ped to the win.pipe(skip(1)) Observable which skips 1 value for every 2 values emitted.

Finally, we pipe the values to mergeAll to merge all the Observables into one.

Then we should see that every third number isn’t emitted.

windowTime

The windowTime operator returns an Observable that emits windows of items with the window period set by the windowTimeSpan.

It takes up to 2 arguments, which is the windowTimeSpan, and the second is an optional argument, which is a scheduler object.

An example would the following:

import { interval } from "rxjs";  
import { windowTime, mergeAll, take, map } from "rxjs/operators";
const nums = interval(1000);  
const result = nums.pipe(  
  windowTime(1000, 5000),  
  map(win => win.pipe(take(2))),  
  mergeAll()  
);  
result.subscribe(x => console.log(x));

The code above has the nums Observable, which emits values start from 0 every second. Then the emitted values are pipe d to the windowTime operator, which starts a window every 5 seconds that’s 1 second long. Then we take 2 values from each window

This will result in 3 values being skipped in each window since values are emitted every minute by nums but we take only 2 values from every window.

windowToggle

windowToggle branches the source Observable values as nested Observable starting from emitting from openings and ending with the closingSelector emits.

It takes up to 2 arguments. The first is the openings , which is an Observable of notifications to start a new window.

The second is the closingSelector which takes the value emitted by the openings and returns an Observable which emits the next or complete signal will close the window.

We can use it as follows:

import { interval, EMPTY } from "rxjs";  
import { windowToggle, mergeAll } from "rxjs/operators";
const interval$ = interval(2000);  
const openings = interval(2000);  
const result = interval$.pipe(  
  windowToggle(openings, i => (i % 3 === 0 ? interval(500) : EMPTY)),  
  mergeAll()  
);  
result.subscribe(x => console.log(x));

We have interval$ Observable which emits a number every 2 seconds. Then we have the same Observable for openings . The emitted values for interval$ are pipe d to the windowToggle operator, which has the openings Observable as the first argument, which emits every 2 seconds. So we start a new window every 2 seconds.

Then we have the second function:

i => (i % 3 === 0 ? interval(500) : EMPTY)

to close the window when the value piped in isn’t divisible by 3. This means that we get every 3 values emitted from interval$ logged.

windowWhen

The windowWhen operator branches out the source Observable using the closingSelector function, which returns an Observable to close the window.

It takes the closingSelector function which takes the value emitted by the openings and returns an Observable which emits the next or complete signal will close the window.

For example, we can use it as follows:

import { interval } from "rxjs";  
import { mergeAll, take, windowWhen, map } from "rxjs/operators";
const interval$ = interval(2000);  
const result = interval$.pipe(  
  windowWhen(() => interval(Math.random() * 4000)),  
  map(win => win.pipe(take(2))),  
  mergeAll()  
);  
result.subscribe(x => console.log(x));

In the code above, we have the interval$ which emits a number every 2 seconds. Then the emitted value is pipe d to the windowWhen operator, which has the closingSelector ve:

() => interval(Math.random() \* 4000)

This means the window will close and reopen Math.random() * 4000 milliseconds.

We should be that some numbers are emitted faster than others.

The windowCount operator branch out the source Observable values as nested Observable with each of them emitting at most windowSize events. windowSize is the size of each window.

windowTime operator returns an Observable that emits windows of items with the window period set by the windowTimeSpan . windowTimeSpan sets the amount of time a window is open.

windowToggle branches the source Observable values as nested Observable starting from emitting from openings and ending with the closingSelector emits. The openings and closingSelector functions are Observables that control the opening and closing of the window for each Observable respectively.

The windowWhen operator branches out the source Observable using the closingSelector function, which returns an Observable to close the window.

Categories
Flow JavaScript

JavaScript Type Checking with Flow — Type Aliases

Flow is a type checker made by Facebook for checking JavaScript data types. It has many built-in data types we can use to annotate the types of variables and function parameters.

In this article, we’ll look at how to create type aliases with Flow to reuse types.

Defining Type Aliases

We can define a type alias in Flow by using the type keyword. For example, we can write:

type Person = {  
  name: string,  
  age: number  
};

Then we can use the same type alias anywhere in our code, including variable declarations:

let person: Person = {  
  name: 'Joe',  
  age: 10  
}

and function signatures:

const getPerson = (person: Person): Person => person;

and classes:

class Employee {  
  person: Person;  
  constructor(person: Person){  
    this.person = person;  
  } getPerson(person: Person): Person {  
    return this.person;  
  }  
}

Type Alias Syntax

We can assign any types to a type alias with the = operator.

For example, we can write:

type UnionAlias = 'a' | 'b' | 'c';

or:

type NumberAlias = number;

We can also define an alias for object types as follows:

type PersonAlias = {  
  name: string,  
  getName(): string,  
};

Type Alias Generics

They can also be parameterized with generic type markers. In this case, we have to pass in actual types to use it as a type for any entity.

For example, we can write:

type GenericPerson<A, B> = {  
  name: A,  
  age: B  
};

Then to use it, we have to pass in types for A and B . For example, we write:

let person: GenericPerson<string, number> = {  
  name: 'Joe',  
  age: 10  
}

Generic type markers can also be applied to methods in type aliases. For example, we can write:

type GenericObject<A, B, C> = {  
  prop: A,  
  method(val: B): C,  
};

Opaque Type Aliases

Opaque type alias hides the type in which the type alias is created from when it’s exported to different files.

We can define an opaque type alias by using the opaque keyword before the type alias definition. For example, we can write:

opaque type Name = string;

Within the file that the opaque type alias is defined, it acts like a regular type alias. For example, we can use the Name alias as follows:

function getName(name: Name): Name {  
  return name;  
}

We can also export it with the export keyword as follows:

export type {Name};

Also, we can add an optional subtyping constraint to an opaque type alias by adding a colon between the subtype and the supertype. The format would be like:

opaque type Alias: SuperType = Type;

For example, we can write:

opaque type PersonAlias = {  
  name: string;  
  age: number;  
  getAgeByName(name: string): number;  
}opaque type AliasAlias: PersonAlias = PersonAlias;  
opaque type VeryOpaque: AliasAlias = PersonAlias;

Then when AliasAlias and VeryOpaque type alias are exported, the other files won’t see the underlying types that composed the PersonAlias type alias.

Opaque Type Alias Type Checking

Within the file where the opaque type alias is defined, it behaves exactly as regular type aliases do.

For example, we can write:

opaque type StringAlias = string;('abc': StringAlias);function concat(x: StringAlias, y: StringAlias): StringAlias {  
  return x + y;  
}  
function toNumberAlias(x: string): StringAlias { return x; }  
function getLength(x: StringAlias): number { return x.length; }

Flow recognizes that StringAlias is just an alias for the string type in the file that StringAlias is defined in.

However, outside the file, StringAlias is recognized as its own type. If we import it in another file as follows:

import type { StringAlias } from './index';

and then try to use the same code as the ones we have above:

function concat(x: StringAlias, y: StringAlias): StringAlias {  
  return x + y;  
}  
function toNumberAlias(x: string): StringAlias { return x; }  
function getLength(x: StringAlias): number { return x.length; }

We’ll get errors since StringAlias is no longer to be compatible with string .

To fix this, we have to add a subtyping constraint to indicate that StringAlias is a subtype of string so that they can be considered to be compatible outside the defining file.

For example, if we export the StringAlias type in one module as follows:

opaque type StringAlias: string = string;  
export type {StringAlias};

Then we can use it in another module as follows:

import type { StringAlias } from './index';function concat(x: StringAlias, y: StringAlias): string {  
  return x + y;  
}  
function toNumberAlias(x: string): string { return x; }  
function getLength(x: StringAlias): number { return x.length; }

As we can see, unlike what we had before, now StringAlias is considered to be compatible with string outside the file that StringAlias is defined in. This is because we made StringAlias a subtype of string with:

opaque type StringAlias: string = string;

Opaque Type Alias Generics

We can add generic type markers to opaque type alias like regular type alias. For example, we can write:

opaque type Obj<A, B, C>: { a: A, b: B } = {  
  a: A,  
  b: B,  
  c: C,  
};

After defining the generic type alias, we can use it by adding actual types in place of the generic type markers. For instance, we can write:

let obj: Obj<number, string, boolean> = {  
  a: 1, b: 'Joe', c: false  
}

Library Definitions

We can use the declare keyword to declare opaque type alias in library definitions. This way, we can omit the underlying type and still optionally include a supertype.

For instance, we can write:

declare opaque type Obj;  
declare opaque type NumberAlias: number;

With Flow, we can define regular and opaque type alias. Regular type alias lets us set any type alias to a name. Opaque type alias hides the underlying type definition in the file that imports the type. We can set a type alias as a supertype of an opaque type alias to make the opaque type alias be compatible with the supertype outside the file that the opaque type is defined in.

Categories
Express JavaScript

Guide to the Express Response Object — More Ways to Send

The Express response object lets us send a response to the client.

Various kinds of responses like strings, JSON, and files can be sent. Also, we can send various headers and status code to the client in addition to the body.

In this article, we’ll look at how to set headers and send status codes with other items, including the set method for setting headers, status for setting response status code, type for setting the Content-Type header value, and the vary method for setting the Vary header value.

Methods

res.set(field [, value])

We can use the set method to set response headers before sending a response.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.set({  
    'Content-Type': 'text/plain',  
    'Content-Length': '100'  
  })  
    .send();  
})  
app.listen(3000);

Then when we make a request to / , we get that the Content-Length header is set to 100 and the Content-Type is set to text/plain .

Note that we have to call send to send the response.

We can verify this with an HTTP client like Postman.

res.status(code)

We can call the status method to add a status code before sending the response.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.status(400).send('Bad Request');  
})
app.listen(3000);

Then we get Bad Request displayed and the 400 response code.

res.type(type)

The type method sets the Content-Type HTTP header to the MIME type determined by the mime.lookup() method from the node-mime package for the specified type.

If type contains the / character, then it sets the Content-Type to type .

This method doesn’t send the response.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.type('.html').send();  
})  
app.listen(3000);

Then we get that the Content-Type response header has the value text/html; charset=utf-8 .

If we have:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.type('.png').send();  
})  
app.listen(3000);

Then we get image/png instead of text/html for the value of Content-Type .

res.vary(field)

The vary method adds the field to the Vary response header if it’s not already there.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.vary('User-Agent').send();  
})  
app.listen(3000);

Then we have the Vary response header set to User-Agent .

The Vary header lets us to content negotiation, which is a mechanism for serving different kinds of data with the same URL.

The user agent can specify what’s best for the server.

The Vary header indicates which headers it’s used for content negotiation.

Since we have the Vary header set to User-Agent , our app uses the User-Agent header to serve different kinds of content according to the user agent of the browser.

Conclusion

The set method lets us set headers before sending our response. It takes an object with the response headers that we want to send.

status method is for setting a response status code before sending it. We can chain it with the response body.

The type method is for setting the Content-Type header value. The returned MIME-type is determined by the mime.lookup() method from node-mime .

The vary method for setting the Vary header value. The Vary header is used for content negotiation, which is serving different content according to the field specified by the Vary header’s value with the same URL.

Categories
Angular JavaScript

Accepting User Input with Angular

Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.

In this article, we’ll look at how to accept user inputs with Angular.

User Input

We can use Angular event bindings to respond to any DOM event.

Many DOM events are triggered by user input. Bindings let us provide a way to get input from users.

For example, we can listen to button clicks as follows:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  onClickMe() {  
    alert("clicked");  
  }  
}

app.component.html :

<button (click)="onClickMe()">Click me!</button>

In the code above, we have the onClickMe method to display an alert.

Then in app.component.html , we added a button which is bound to the click and calls onClickMe when it’s clicked.

Get User Input From the $event Object

DOM events carry a payload of information that may useful to the component. We can access that information by referencing the $event object.

For example, we can write:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  keysPressed: string[] = [];  
  onKeyUp(event) {  
    this.keysPressed.push(event.key);  
  }  
}

app.component.html :

<input (keyup)="onKeyUp($event)" />  
<p>{{keysPressed.join(',')}}</p>

In the code above, we have the onKeyUp method of AppComponent which called on the keyup event of input.

In onKeyUp , we push the key that was pressed into the this.keyPressed array.

Then in the template, we call join to combine the strings of the keys that are pressed together.

Type the $event

We can use the KeyboardEvent type to type $event for keyboard events.

We can type the element with the HTMLInputElement type.

For example, we can write the following code:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  values: string[] = [];  
  onKeyUp(event: KeyboardEvent) {  
    this.values.push((event.target as HTMLInputElement).value);  
  }  
}

app.component.html :

<input (keyup)="onKeyUp($event)" />  
<p>{{values.join(',')}}</p>

In AppComponent above, we set the event to the KeyboardEvent type and casted the event.target to the HTMLInputElement type.

This way, we get auto-complete and so we’re less likely to make mistakes.

However, passing in the whole $event object to the component reveals too many details about the event and so creates tight coupling between the template and the component.

Get User Input From a Template Reference Variable

We can use template reference variables to get input values.

For example, we can do that as follows:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {}

app.component.html :

<input #box (keyup)="null" />  
<p>{{box.value}}</p>

On the code above, we have the keyup handler set to null and we added the #box reference variable to the input box.

Then we render the value of the #box input by referencing box.value .

When we type in something into the input box, we’ll see the value displayed in the p element.

This is better than using the $event object to get the value since it doesn’t we don’t have to access the $event object to get the value. Key Event Filtering

We can listen for specific keypresses in an element by specifying the key with the key attribute.

For example, if we want to listen to presses of the Enter key, we can write the following:

app.component.html :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  onEnter(value) {  
    alert(value);  
  }  
}

app.component.html :

<input #box (keyup.enter)="onEnter(box.value)" />

In the code above, we have the onEnter method in AppComponent that takes the value entered into the input box.

Then in app.component.html , we added the #box template variable to the input and have:

(keyup.enter)="onEnter(box.value)"

to listen to keypresses of the Enter key and pass in the value entered into the input to display the alert by calling onEnter with the value passed in.

On Blur

We can listen to the blur event of an element by passing an event listener to an element.

For example, we can write:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  value: string;  
  update(value) {  
    this.value = value;  
  }  
}

app.component.html :

<input #box (blur)="update(box.value)" />  
<p>{{value}}</p>

In the code above, we add the #box template variable to the input box and we added a blur event listener by setting (blur) to the update method in AppComponent .

The update method takes an inputted value and sets it to this.value so we can display it in our template.

Then when we type in something into the input and then move the cursor away from the input, we’ll see the value displayed in the p element.

Conclusion

We can handle user inputs by listening to various event listeners.

To get the event object emitted by the event, we can reference the $event object.

To make getting inputted values easier, we can add a template reference variable to the element in the template and then get the properties we want from it.

Categories
JavaScript Vue

How to Conditionally Render Elements in Vue

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at various ways to render items conditionally on the screen with Vue.js by using the v-show directive.

Also, we’ll look at the performance implications of combining v-if and v-for is various ways.

v-show

The v-show directive is used to show something when the expression we passed into it is truthy.

For example, we can use it as follows:

<h1 v-show="show">Hi</h1>

The difference between v-show and v-if are that v-show elements remain in the DOM even though is hidden.

On the other hand, v-if elements are hidden by removing them from the DOM.

Also, v-if removes event listeners and child components inside conditional blocks are destroyed if they’re hidden and recreated when v-if ‘s expression is truthy.

v-if elements are also different in that if the condition is falsy during conditional render, it won’t do anything. It won’t be rendered until the expression becomes truthy.

v-if has higher toggling than v-show since DOM manipulating and attaching event listeners have to be done when things are toggled.

Therefore, if things need to be toggled often, v-show is more efficient.

v-if with v-for

v-for has higher priority than v-if if they’re used together.

However, we shouldn’t use them together because of the higher precedence of v-for over v-if .

If we want to filter some elements out when we render items from an array, we should use a computed property.

If we only render a small fraction of array elements, it has to iterate over the entire list and then check if the expression we set it truthy.

For example, the following JavaScript and HTML code:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"]  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-for="person in persons" v-if='person !== "Joe"'>  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

is not very efficient since every time the loop is rendered, Vue has to iterate through every element and then check if person !== “Joe” is true .

Instead, we should use a computed property as follows:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"]  
  },  
  computed: {  
    personsWithoutJoe() {  
      return this.persons.filter(p => p !== "Joe");  
    }  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-for="person in personsWithoutJoe">  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

The code above is more efficient because personsWithoutJoe is only recomputed when persons change.

Also, only the items in personsWithoutJoe is iterated through during render, so v-for doesn’t have to loop through all the items.

There’s also less logic in the template, which keeps it clean. Maintenance is much easier.

We can also get performance benefits from moving v-if to the parent element that has the v-for , so whatever’s inside is only rendered when the condition is met.

For example, if we have:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"],  
    show: false  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-if="show">  
        <div v-for="person in persons">  
          {{person}}  
        </div>  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then nothing is rendered since show is false . Vue doesn’t have to do the work to look at whatever’s inside.

This is much better than:

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-for="person in persons" v-if="show">  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, Vue has to loop through each entry and check if the condition in the v-if returns a truthy value.

As we can see, even though the code is only slightly different, but the performance implications are big.

Conclusion

v-show is similar to v-if , except that items with v-show stays in the DOM no matter if it’s shown or not.

Also, we should be careful when we combine v-for and v-if .

First, v-for takes precedence over v-if if applied to the same element.

Also, we shouldn’t use them on the same element since Vue has to check each element for v-if ‘s condition in every iteration.

If we want to render a filtered list, we should use a computed property.

If we want to check if we should render the whole array, we should move v-if to the parent of the element with v-for , so that if v-if ‘s condition is falsy, then Vue won’t render the items in there.