Categories
Flow JavaScript

JavaScript Type Checking with Flow — Intersection Types

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 piece, we’ll look at how to use intersection types to create variables that accept a combination of multiple types.


Defining Intersection Types

We can create intersection types by separating multiple types with an & sign as follows:

Type1 & Type2 & ... & TypeN

We can also break the expression above into multiple lines with the leading & sign:

type Bar =  
  & Type1  
  & Type2  
  & ...  
  & TypeN

Also, we can create intersection types from other intersection types:

type A = Type1 & Type2;  
type B = Type3 & Type4;  
  
type Foo = A & B;

Properties of Intersection Types

When we call a function that accepts an intersection type, we must pass in data that has all of those types. But inside the function, we can treat them as being one of the types in the intersection type.

For example, if we define the following function:

type A = { a: number };  
type B = { b: boolean };  
type C = { c: string };  
  
function foo(value: A & B & C) {  
    
}

Then we can treat value as having to be any one of A , B and C, as follows:

function foo(value: A & B & C) {  
  let a: A = value;  
  let b: B = value;  
  let c: C = value;    
}

Impossible Intersection Types

We can create intersection types that are impossible. For example, we can create a type that’s an intersection of string and boolean, as follows:

type StringBoolean = string & boolean;

This type is useless since no value can be both a string and a boolean, so we can’t assign anything to it.


Intersections of Object Types

An intersection of object types means that an object of the intersection type must have all the properties of both types.

For example, suppose we have the following intersection type:

type Foo = { foo: string };  
type Bar = { bar: boolean };
type FooBar = Foo & Bar;

The variable that we create of type FooBar must have all the properties of both Foo and Bar:

let foobar : FooBar = {  
  foo: 'abc',  
  bar: true  
};

When two object types have the same property name but a different type, then when they’re intersected together, the new property with the same name will have the intersection of both types as the new type.

For example, suppose we have:

type Foo = { foo: string };  
type Bar = { foo: boolean };
type FooBar = Foo & Bar;

Then foo will have the string & boolean intersection type, which means that no value can be set to it.

With intersection types, we can create types that have all the properties of each type that form the intersection type. We can also create intersection types from primitive types, but they’re useless since nothing can be assigned to variables of those types.

This means that intersection types are useful for object types mostly.

Categories
Express JavaScript

Guide to the Express Response Object — Files and JSON

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 various properties of the response object, including files and JSON responses.

Methods

res.download

res.download sends a file response to the server.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.download('./public/foo.txt');  
})
app.listen(3000, () => console.log('server started'));

Then when a request is made to this route, then we’ll get a file downloaded.

We can save a file with a different than the file on the server by writing:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  res.download('./files/foo.txt', 'foobar.txt');  
});
app.listen(3000, () => console.log('server started'));

The file foo.txt from the server will be saved as foobar.txt by the client.

The download method also takes an error handler in case the download response fails.

For example, we can handle errors with the built-in error handler as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res, next) => {  
  res.download('./files/foo.txt', 'foobar.txt', err => next(err));  
});
app.listen(3000, () => console.log('server started'));

We called next with the error object passed in to pass it onto the error handler.

res.end([data] [, encoding])

res.end ends the response process. The method comes from response.end() of the http module.

We can use it to end the response without sending any data. To respond with data, we can use res.send() or other methods.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  res.status(404).end();  
});
app.listen(3000, () => console.log('server started'));

Then we sent a 404 response back to the client with no data.

res.format(object)

The res.format method takes the Accept HTTP header from the request object and use res.accepts to select a handler for the request.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  res.format({  
    'text/plain': () => {  
      res.send('hi');  
    }, 'text/html': () => {  
      res.send('<p>hi</p>');  
    }, 'application/json': () => {  
      res.json({ message: 'hi' });  
    }, 'default': () => {  
      res.status(406).end();  
    }  
  })  
});
app.listen(3000, () => console.log('server started'));

If we send a GET request to / with Accept header’s value set to text/plain , we get hi . If we send text/html as the Accept header’s value, we get <p>hi</p> , and so on.

default specifies the default response if none of the response types are matched.

It’ll work even if we abbreviate the MIME type names to something shorter:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  res.format({  
    text: () => {  
      res.send('hi');  
    }, html: () => {  
      res.send('<p>hi</p>');  
    }, json: () => {  
      res.json({ message: 'hi' });  
    }, default: () => {  
      res.status(406).end();  
    }  
  })  
});
app.listen(3000, () => console.log('server started'));

Then we get the same thing as before.

res.get(field)

The get method returns the HTTP response header specified by field . The match isn’t case sensitive.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {    
  res.send(res.get('Content-Type'));  
});
app.listen(3000, () => console.log('server started'));

res.json([body])

res.json lets us send a JSON response to the client. The parameter can be any JSON type, including object, array, string, Boolean, number, or null.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.json({ message: 'hi' });  
})
app.listen(3000, () => console.log('server started'));

Then we get:

{"message":"hi"}

as the response.

res.jsonp([body])

We can use this to send a JSON response with JSONP support. It returns a callback with the JSON body passed in.

For example, we can use it as follows:

const express = require('express');  
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {  
  res.jsonp({ user: 'foo' });  
});
app.listen(3000, () => console.log('server started'));

If we send a GET request with ?callback=cb as the query string, then we get:

// typeof cb === 'function' && cb({"user":"foo"});

as the response. If we leave out the callback search parameter, then we get a normal JSON response:

{  
    "user": "foo"  
}

Conclusion

We can send various kinds of responses easily with the response object.

To send files, we can use download .

To send different things according to the Accept request header, we can use the format method.

Finally, to send JSON, we can use the json or jsonp methods depending on if we need to call a callback function on the client or not.

Categories
JavaScript Rxjs

More Rxjs Transformation Operators — mergeScan and Pluck

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

In this article, we’ll look at some transformation operators like mergeScan , pairwise , partition , and pluck operators.

mergeScan

The mergeScan operator applies an accumulator function over the source Observable where the accumulator function itself returns an Observable, where each intermediate Observable returned is merged into the output Observable.

It takes up to 3 arguments. The first is an accumulator function that’s called on each source value.

The second argument is the seed parameter, which takes the initial accumulation value.

The last argument is an optional argument which takes the maximum number of concurrent input Observables to be subscribed to concurrently.

For example, we can use it as follows:

import { of, interval } from "rxjs";  
import { mapTo, mergeScan } from "rxjs/operators";
const interval$ = interval(5000);  
const one$ = interval$.pipe(mapTo(1));  
const seed = 0;  
const count$ = one$.pipe(mergeScan((acc, one) => of(acc + one), seed));  
count$.subscribe(x => console.log(x));

The code above has the interval$ Observable which is mapped to the value 1 with the mapTo operator. Then we set the seed initial value to 0.

Then we send the emitted values of the interval$ Observable to the accumulator function via the mergeScan operator, which keeps adding 1 as the values from interval$ is emitted. Then we get the emitted number from $count when we subscribe to count$ .

pairwise

pairwise groups pairs of consecutive emissions from the source Observable together then emit them as an array 2 values.

It takes on arguments.

For example, we can use it as in the following example:

import { of } from "rxjs";  
import { pairwise } from "rxjs/operators";
const of$ = of(1, 2, 3, 4, 5, 6);  
const pair$ = of$.pipe(pairwise());  
pair$.subscribe(x => console.log(x));

The code above will group the emitted values from the of$ Observable into pairs with the pairwise() operator then emitted the values. Then we get the following output from the console.log :

[1, 2]  
[2, 3]  
[3, 4]  
[4, 5]  
[5, 6]

partition

The partition operator splits the source Observable into 2, where one has the values that satisfy a predicate and the other with values that doesn’t.

It takes up to 2 arguments. The first is the predicate , which is a function that evaluates each value emitted by the source Observable. Then if the function returns true , then the value emitted on the first return Observable in the emitted array. Otherwise, it’s emitted in the second Observable with that emitted array.

The second is the thisArg , which lets us set the value of this inside the predicate function.

For instance, we can use it as follows:

import { of } from "rxjs";  
import { partition } from "rxjs/operators";
const of$ = of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  
const parts = of$.pipe(partition(x => x % 2 === 0));  
const [even, odd] = parts;  
odd.subscribe(x => console.log(`odd numbers: ${x}`));  
even.subscribe(x => console.log(`even numbers: ${x}`));

In the code above, we have the of$ Observable with some numbers. Then we pipe it into the partition operator, which takes a predicate function that checks whether a number emitted from the of$ Observable is even.

parts will be set to the 2 Observables returned from the partition operator. The even Observable has the even numbers emitted, and the odd Observable has odd numbers emitted.

Then we get the following output from the odd Observable:

odd numbers: 1  
odd numbers: 3  
odd numbers: 5  
odd numbers: 7  
odd numbers: 9

Then we get the following output from the even Observable:

even numbers: 2  
even numbers: 4  
even numbers: 6  
even numbers: 8  
even numbers: 10

pluck

The pluck operator map each emitted value from the source Observable to its specified nested property.

It takes one argument which is the properties object, which are the nested properties to pluck from each source value.

For example, we can use it as follows:

import { of } from "rxjs";  
import { pluck } from "rxjs/operators";
const people = [  
  { name: { firstName: "Mary" }, age: 10, gender: "female" },  
  { name: { firstName: "Joe" }, age: 11, gender: "male" },  
  { name: { firstName: "Amy" }, age: 10, gender: "female" }  
];  
const people$ = of(...people);  
const plucked = people$.pipe(pluck("name", "firstName"));  
plucked.subscribe(x => console.log(x));

The code above, has a people array where each entry has a name object. We emit the values with the of operator and then pipe the emitted values and use pluck to get the nested property firstName , which is inside name .

Then we should get:

Mary  
Joe  
Amy

as the output on the last line.

mergeScan applies an accumulator function over the source Observable where the accumulator function itself returns an Observable. Then each intermediate Observable returned is merged into the output Observable and emitted together.

pairwise groups pairs of consecutive emissions from the source Observable together then emit them as an array 2 values.

The partition operator splits the source Observable into 2, where one has the values that satisfy the condition returned in the predicate function and the other with values that doesn’t.

The pluck operator map each emitted value from the source Observable the value of the specified nested property.

Categories
JavaScript Vue

List Rendering with Vue.js — Numbers, Components, and Templates

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 rendering a range of numbers, rendering components and templates, and more.

v-for with a Range

v-for can take an integer to render a range of numbers. For example, if we have the following:

src/index.js :

new Vue({  
  el: "#app",  
  data: {}  
});

index.html :

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

Then we see:

1 2 3 4 5 6 7 8 9 10

v-for on a Template

We can use v-for to loop through template elements. For example, we can write:

src/index.js :

new Vue({  
  el: "#app",  
  data: {}  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="[https://cdn.jsdelivr.net/npm/vue/dist/vue.js](https://cdn.jsdelivr.net/npm/vue/dist/vue.js)"></script>  
  </head> <body>  
    <div id="app">  
      <template v-for="num in 10">  
        <span>  
          {{num}}  
        </span>  
        <span>|</span>  
      </template>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get:

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

displayed on the screen.

v-for with v-if

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: {  
    numbers: [1, 2, 3, 4, 5]  
  }  
});

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">  
      <span v-for="num in numbers" v-if="num !== 3">  
        {{num}}  
      </span>  
    </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 num !== 3 is true .

Instead, we should use a computed property as follows:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    numbers: [1, 2, 3, 4, 5]  
  },  
  computed: {  
    not3() {  
      return this.numbers.filter(p => p !== 3);  
    }  
  }  
});

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">  
      <span v-for="num in not3">  
        {{num}}  
      </span>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

The code above is more efficient because not3 is only recomputed when numbers change.

Also, only the items in not3 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.

v-for with a Component

We can use v-for on custom components just like with any other element.

For example, we can write the following:

src/index.js :

Vue.component("num", {  
  props: ["num"],  
  template: "<span>{{num}}</span>"  
});new Vue({  
  el: "#app",  
  data: {  
    numbers: [1, 2, 3, 4, 5]  
  }  
});

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">  
      <num v-for="num in numbers" :num="num" :key="num" />  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get:

12345

displayed on the screen.

Note that we have the :key attribute provided. This is required since Vue 2.2.0.

Also, we passed num into the num component’s num prop by writing:

:num="num"

This lets us inject what we want to the component, reducing coupling between them.

Conclusion

We can render a range of numbers with v-for by providing it with a number instead of an array or an object.

v-for and v-if shoudn’t be used together so that v-if doesn’t have to run in each iteration and we can also reduce the number of items that are iterated through.

Also, we can loop through template and components with v-for like any other element.

Categories
Express JavaScript Nodejs

Parse Cookies in Requests in Express Apps with Cookie-Parser

By default, Express 4.x or later doesn’t come with any middleware to parse cookies.

To do this, we can add the cookie-parser middleware.

In this article, we’ll look at how to use it to parse cookies sent with requests.

Adding the Package

We can install the package by running:

npm install cookie-parser

Then we can write:

const express = require('express')  
const cookieParser = require('cookie-parser')  
  
const app = express()  
app.use(cookieParser())

to add the middleware to our app.

Methods

cookieParser(secret, options)

The cookie-parser middleware’s cookieParser function takes a secret string or array of strings as the first argument and an options object as the second argument.

The secret is optional. If it’s not specified it won’t parse signed cookies. If a string is provided, it’ll be used as the secret. If an array of strings is provided, then each secret will be tried for decoding the signed cookie

options is an object that is passed into the cookie.parse as the second option.

cookieParser.JSONCookie(str)

The JSONCookie parses a JSON cookie. This returns the pared JSON value if it’s a JSON cookie. It’ll return the passed value otherwise.

cookieParser.JSONCookies(cookies)

The method will iterate over the keys and call JSONCookie on each value and replace the original value with the parsed value. This returns the same object that’s passed in.

cookieParser.signedCookie(str, secret)

signedCookie parses a cookie as a signed cookie. It’ll return the parsed unsigned value if it was a signed cookie and the signature is valid. If the value wasn’t signed, then the original value is returned. If the value is signed but the cookie can’t be validated with the secret, then false is returned.

cookieParser.signedCookies(cookies, secret)

This method will iterate over the keys and check if any value is a signed cookie. If it’s signed and the signature is valid, then the key will be deleted from the object and added to the new object that’s returned.

The secret can be an array or string. If it’s a string, then it’ll check against the string secret. Otherwise, each cookie will be checked with each string in the array.

The JSONCookie, JSONCookies, signedCookie and signedCookies methods will be automatically invoked depending on the type of cookie sent from the client. Parsing Unsigned Cookies

A simple example is parsing unsigned cookies as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();
app.use(bodyParser.json());  
app.use(cookieParser());
app.get('/', (req, res) => {  
  res.send(req.cookies);  
});
app.listen(3000);

Then when we send a GET request with the Cookie header’s value set to foo=bar , then we get:

{  
    "foo": "bar"  
}

as the response since req.cookies has the parsed cookie.

Parsing Signed Cookies

We can send a signed cookie and parse it as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  
const secret = 'secret';
app.use(bodyParser.json());  
app.use(cookieParser(secret));
app.get('/cookie', (req, res) => {  
  res  
    .cookie('foo', 'bar', { signed: true })  
    .send();  
});
app.get('/', (req, res) => {    
  res.send(req.signedCookies);  
});
app.listen(3000);

The code has the /cookie endpoint to send the signed cookie to the client.

{ signed: true }

will make Express sign the cookie.

Then from the client, when we make a request to / , we get the signed cookie via req.signedCookies and so we get:

{  
    "foo": "bar"  
}

as the response from / .

Conclusion

We can use the cookie-parser middleware to parse the cookies.

It can parse both signed and unsigned cookies. To parse a signed cookie, we just have to sign our cookie with a secret and then cookie-parser can decode the cookie if we pass in the secret to the cookieParser middleware function.

The JSONCookie, JSONCookies, signedCookie and signedCookies methods will be automatically invoked depending on the type of cookie sent from the client.