Sunday, July 1, 2018

401 on all browsers except Chrome Canary

Encountered a weird case where the program works on Chrome Canary, and then causes http 401 unauthorized on all other browsers (Firefox, Safari, Chrome). I even installed a new browser (Opera) to see if the code is working there, but to no avail.

It turns out Chrome Canary automatically uses the credentials (cookie) even if credentials: 'include' is not passed to fetch's options parameter.

So to make fetch work on all browsers, instead of this:

await fetch('urlHere');

Pass credentials: 'include' option explicitly instead:
await fetch('urlHere', {credentials: 'include'});


Saturday, June 2, 2018

Nameless interface with TypeScript

There are only two hard things in Computer Science: cache invalidation and naming things. -- PHil Karlton


Why give names to actions when your action and reducer can discriminate an action based on type (e.g., MyJobActionType) ?
export const enum MyJobActionType
{
    MY_JOB               = 'MY_JOB',

    MY_JOB_UI            = 'MY_JOB_UI',
    MY_JOB_DATA_FETCHING = 'MY_JOB_DATA_FETCHING',
    MY_JOB_DATA_FETCHED  = 'MY_JOB_DATA_FETCHED',

}

export type MyJobAction = IMyJobAction | IMyJobUIAction | IMyJobDataFetchingAction | IMyJobDataFetchedAction;

interface IMyJobAction extends Action
{
    type: MyJobActionType.MY_JOB;
    payload?: {
        jobId: 'new' | number;
    };
}

interface IMyJobUIAction extends Action
{
    type: MyJobActionType.MY_JOB_UI;
    ui: React.ComponentClass;
}

interface IMyJobDataFetchingAction extends Action
{
    type: MyJobActionType.MY_JOB_DATA_FETCHING;
}

interface IMyJobDataFetchedAction extends Action
{
    type: MyJobActionType.MY_JOB_DATA_FETCHED;
    data: IPagedDto<IPagedMyJobPostDto>;
}

Reducer:
export const myJobViewModelReducer = produce((
    draft: IMyJobViewModel = {
        view : null,
        model: {
            gridData: no.data
        }
    },
    action: MyJobAction
) =>


Action:
async function loadUI(dispatch: Dispatch<MyJobAction>)
{
    const component = (await import(/* webpackChunkName: 'myJob' */ './')).default;

    const uiAction: MyJobAction = {
        type: MyJobActionType.MY_JOB_UI,
        ui  : component
    };

    await dispatch(uiAction);
}


So don't name things then:
export type MyJobAction =
    {
        type: MyJobActionType.MY_JOB;
        payload?: {
            jobId: 'new' | number;
        };
    }
    |
    {
        type: MyJobActionType.MY_JOB_UI;
        ui: React.ComponentClass;
    }
    |
    {
        type: MyJobActionType.MY_JOB_DATA_FETCHING;
    }
    |
    {
        type: MyJobActionType.MY_JOB_DATA_FETCHED;
        data: IPagedDto<IPagedMyJobPostDto>;
    }
    ;

Are you worried someone might use the wrong payload (e.g., payload, ui, data) when dispatching an action? Don't worry, TypeScript is a smart language.




And just like that, TypeScript can infer that only the ui property is if a good discriminator is used, e.g., type: MyJobActionType.MY_JOB_UI




By the way, don't use the Dispatch type definition from redux, use the one from react-redux, it has more comprehensive type-checking. Upgraded to Redux 4, no more type definition problem.


So if you want TypeScript to type-check your direct object parameter to dispatch function, use react-redux's Dispatch type definition instead: Use Redux 4.0 instead, it comes with the correct type definition.



Finally, correct the properties of the object structure that matches type: MyJobActionType.MY_JOB_UI




Less interfaces, less names need to come up with.

Thursday, May 31, 2018

timestamptz is easier to adjust than timestamp

create table z(id int primary key, _timestamp timestamp, _timestamptz timestamptz);
insert into z(id, _timestamp, _timestamptz) values (1, '2018-05-04T17:37:00Z', '2018-05-04T17:37:00Z');
set timezone to 'Asia/Manila';
select 
    _timestamp as "indeterminate timezone", -- timestamp is an indeterminate timezone. for the purpose of this demo, we are storing UTC-based data
    _timestamptz as "follows set timezone to XXX", 
    _timestamp at time zone 'UTC' at time zone 'Asia/Tokyo' as "local: Japan", 
    _timestamptz at time zone 'Asia/Tokyo' as "local: Japan",
    _timestamp at time zone 'UTC' at time zone 'Asia/Manila' as "local: Philippines", 
    _timestamptz at time zone 'Asia/Manila' as "local: Philippines"
from z;

-[ RECORD 1 ]---------------+-----------------------
indeterminate timezone      | 2018-05-04 17:37:00
follows set timezone to XXX | 2018-05-05 01:37:00+08
local: Japan                | 2018-05-05 02:37:00
local: Japan                | 2018-05-05 02:37:00
local: Philippines          | 2018-05-05 01:37:00
local: Philippines          | 2018-05-05 01:37:00

set timezone to 'Asia/Tokyo';
select 
    _timestamp as "indeterminate timezone", -- timestamp is an indeterminate timezone. for the purpose of this demo, we are storing UTC-based data
    _timestamptz as "follows set timezone to XXX", 
    _timestamp at time zone 'UTC' at time zone 'Asia/Tokyo' as "local: Japan", 
    _timestamptz at time zone 'Asia/Tokyo' as "local: Japan",
    _timestamp at time zone 'UTC' at time zone 'Asia/Manila' as "local: Philippines", 
    _timestamptz at time zone 'Asia/Manila' as "local: Philippines"
from z;

-[ RECORD 1 ]---------------+-----------------------
indeterminate timezone      | 2018-05-04 17:37:00
follows set timezone to XXX | 2018-05-05 02:37:00+09
local: Japan                | 2018-05-05 02:37:00
local: Japan                | 2018-05-05 02:37:00
local: Philippines          | 2018-05-05 01:37:00
local: Philippines          | 2018-05-05 01:37:00


If we use timestamp field type instead of timestamptz, everytime we need to see the local time in another time zone, we have to convert it to UTC first before we can convert it to a local timezone, e.g.,

_timestamp at time zone 'UTC' at time zone 'Asia/Tokyo' as "local: Japan", 
_timestamp at time zone 'UTC' at time zone 'Asia/Manila' as "local: Philippines", 

Whereas if we use timestamptz upfront, we don't need to convert the data to UTC first before we can adjust it to local, we can just adjust it straight to local, e.g.,
_timestamptz at time zone 'Asia/Tokyo' as "local: Japan",
_timestamptz at time zone 'Asia/Manila' as "local: Philippines"

Another benefit of using timestamptz field type and saving UTC-based data to it, is we can set a local timezone per database session, and Postgres will present the UTC data in local timezone, e.g.,
set timezone to 'Asia/Manila';

select 
    _timestamptz as "follows set timezone to XXX"
from z;

-[ RECORD 1 ]---------------+-----------------------
follows set timezone to XXX | 2018-05-05 01:37:00+08

select 
    _timestamptz + interval '1 day' as "follows set timezone to XXX"
from z;

-[ RECORD 1 ]---------------+-----------------------
follows set timezone to XXX | 2018-05-06 01:37:00+08



set timezone to 'Asia/Tokyo';

select 
    _timestamptz as "follows set timezone to XXX"
from z;

-[ RECORD 1 ]---------------+-----------------------
follows set timezone to XXX | 2018-05-05 02:37:00+09

select 
    _timestamptz + interval '1 day' as "follows set timezone to XXX"
from z;

-[ RECORD 1 ]---------------+-----------------------
follows set timezone to XXX | 2018-05-06 02:37:00+09



set timezone to 'UTC';

select 
    _timestamptz as "follows set timezone to XXX"
from z;

-[ RECORD 1 ]---------------+-----------------------
follows set timezone to XXX | 2018-05-04 17:37:00+00

select 
    _timestamptz + interval '1 day' as "follows set timezone to XXX"
from z;

-[ RECORD 1 ]---------------+-----------------------
follows set timezone to XXX | 2018-05-05 17:37:00+00

Whereas if we used timestamp field type instead of timestamptz, Postgres won't apply set timezone to XXX to the timestamp field type, timestamp is always presented as-is. And usage of timestamp field type should be documented, since timestamp is an indeterminate timezone, no one knows whether the developer designed it to be stored of local timezone, or was it designed to be stored of UTC data. Whereas with timestamptz, it is implied that we should only store UTC-based data to it, doing otherwise is a fool's errand.

Wednesday, May 30, 2018

React readability

Let's say you have this view model controlled by Redux reducer. Its view (React.ComponentClass) property is code-splitted by webpack, so the view is dynamically loaded (e.g., from nested routing by redux-first-router's thunk). Which would require the view be nullable.

export interface IJobFormViewModel
{
    view: React.ComponentClass | null;
    model: IJobFormModel;
}

export interface IJobFormModel
{
    jobId?: number | 'new';

    // lookups
    states: IStateCityDto[];
    durationTypes: IDurationTypeDto[];
    locationTypes: ILocationTypeDto[];

    // form's initial values
    initialValues?: IJobDto;
}

There are three ways the parent component can render the nested component.

Option 1:
const {jobId} = this.props.rootState.jobForm.model;

const JobFormView =
    this.props.rootState.jobForm.view ?
        <this.props.rootState.jobForm.view/>
        :
        <></>;

return <>
    <Helmet>
        <title>My Job Posts</title>
    </Helmet>

    <ReactTable
       ...
    />


    {jobId && JobFormView}

</>;

That's ok, but it's not readily obvious that the JobFormView is a component, it could just be a number, string or date only.


Option 2:
const {jobId} = this.props.rootState.jobForm.model;

const JobFormView = this.props.rootState.jobForm.view || 'span';

return <>
    <Helmet>
        <title>My Job Posts</title>
    </Helmet>

    <ReactTable
       ...
    />


    {jobId && <JobFormView/>}

</>;


Looks good, however the span tag would be included in page's markup whenever the nested view is not yet loaded.

You might be tempted to use this, but this won't work.
const JobFormView = this.props.rootState.jobForm.view || 'React.Fragment';


<React.Fragment> tag is a compiler magic, it will not appear on page's markup. However the following, not only it is a compiler error

const BeeAre = 'br';
const RF = 'React.Fragment';

return <>
    Hello
    <BeeAre/>
    <RF/>
    World
</>;





It would also cause error on browser




Besides 'React.Fragment' is a magic string, yet it does not do any magic, it just makes the markup invalid.

Option 3
const {jobId} = this.props.rootState.jobForm.model;

const JobFormView = this.props.rootState.jobForm.view;

return <>
    <Helmet>
        <title>My Job Posts</title>
    </Helmet>

    <ReactTable
       ...
    />


    {jobId && JobFormView && <JobFormView/>}

</>;


That's the perfect option, not only that the component is obvious, there are no extraneous markup (e.g., span) that would appear on page when the nested view is not yet loaded.

Tuesday, May 29, 2018

ReactTable accessing the type definition

There are two ways to do that.

First approach, import all of the react-table.

import * as ReactTable from 'react-table';

class Something extends.ReactComponent<{}, {}>
{
   private table: ReactTable.Instance;

   public render(): React.ReactNode
   {
      return <>
          <ReactTable.default
             ...
          >
             {(state, makeTable, instance) =>
             {
                 this.table = instance;
                 return makeTable();
             }
          </ReactTable>
      <>;
   }
}

<ReactTable.default ...> is a leaky abstraction though. All the advances in adding syntactic sugars to TypeScript/ES6, and yet some devs still want to leak the abstraction, heretic! Might as well just use de-sugarized import:

const ReactTable = require('react-table');

   // now usage of .default is excusable

   <ReactTable.default


To avoid using the .default directly, just import ReactTable and its type definition separately

import ReactTable, * as ReactTableTypes from 'react-table';

class Something extends.ReactComponent<{}, {}>
{
   private table: ReactTableTypes.Instance;

   public render(): React.ReactNode
   {
      return <>
          <ReactTable
             ...
          >
             {(state, makeTable, instance) =>
             {
                 this.table = instance;
                 return makeTable();
             }
          </ReactTable>
      <>;
   }
}

That's cleaner, you can use ReactTable without the default property. This is possible though:

import ReactTable, * as ReactTableTypes from 'react-table';

class Something extends.ReactComponent<{}, {}>
{
   private table: ReactTableTypes.Instance;

   public render(): React.ReactNode
   {
      return <>
          <ReactTableTypes.default
             ...
          >
             {(state, makeTable, instance) =>
             {
                 this.table = instance;
                 return makeTable();
             }
          </ReactTable>
      <>;
   }
}


But who would do that?

Monday, May 28, 2018

TypeScript is the best for Redux


With the following payload signature..

import { Action } from 'redux';

import { IProfileData } from './model';

export const enum ProfileActionType
{
    PROFILE           = 'PROFILE',
    PROFILE_UI        = 'PROFILE_UI',
    PROFILE_DATA      = 'PROFILE_DATA',
    PROFILE_POST_DATA = 'PROFILE_POST_DATA'
}

export interface IProfileAction extends Action
{
    type: ProfileActionType;

    payload: Partial<{
        [ProfileActionType.PROFILE_UI]: React.ComponentClass;

        [ProfileActionType.PROFILE_DATA]: IProfileData;
    }>;
}


..it's still possible to wrongly choose the correct payload:






And you cannot even pass the correct property as-is:



You must use the null-assertion operator, exclamation mark:




A better way would be is to separate the action data structures for UI and Data, and lump them in an action selector (ProfileAction):

export type ProfileAction = IProfileUIAction | IProfileDataAction;

interface IProfileUIAction extends Action
{
    type: ProfileActionType.PROFILE_UI;
    component: React.ComponentClass;
}

interface IProfileDataAction extends Action
{
    type: ProfileActionType.PROFILE_DATA;
    data: IProfileData;
}

With that, only the component property of ProfileAction will be available for ProfileActionType.PROFILE_UI:



Likewise with ProfileActionType.PROFILE_DATA, only the data property of ProfileAction will be available from ProfileActionType's intellisense.



And that is not just an intellisense feature, it's a language feature. So if you try to get the data property from ProfileAction when the condition (switch case ProfileActionType.PROFILE_UI) is in ProfileActionType.PROFILE_UI, it will not be possible. So awesome!




Likewise when the condition is in ProfileActionType.PROFILE_DATA, you cannot selection action's component property:




You can only choose data property from the action when the condition is in ProfileActionType.PROFILE_DATA:




TypeScript truly feels magical that it can infer the right data structure based on the condition. If you try to select the properties from action outside of switch condition, you can't select the component property neither the data property.




It's also a compiler error:




It's also a compiler error to create an object that does not match from the type's selector:




You can only create an object that matches the type: ProfileActionType.PROFILE_UI

Sunday, May 27, 2018

Postgres timestamp





Happy Coding!

Postgres UTC data type

There's really no type of timestamp with time zone with Postgres. Time zone is not stored, everything is stored as UTC. The time zone is only used for presentation purposes.











Happy Coding!

Saturday, May 26, 2018

Typescript properties concatenation

TypeScript has a unique functionality, it can concatenate properties inline.

Given these following classes from C#
public class PagedDto<T>
{
    public IList<T> Data { get; set; }
    public int Pages { get; set; }
}

public class PagedCityDto
{
    public int CityId { get; set; }
    public string CityName { get; set; }        

    public int StateId { get; set; }
    public string StateName { get; set; }
}   


The above are translated to these:
export interface IPagedDto<T>
{
    data: T[];
    pages: number;
}

export interface IPagedCityDto
{
    cityId: number;
    cityName: string;

    stateId: number;
    stateName: string;
}


Then the following properties concatenation..
interface IComponentState
{
    grid: IPagedDto<IPagedCityDto> & {
        loading: boolean;
    };
}

..is expanded to:
interface IComponentState
{
    grid: {
        data: IPagedCityDto[];
        pages: number;
        loading: boolean;
    };
}


Why would we do concatenation? Why not just put the loading property out-of-band from grid property like this?
interface IComponentState
{
    grid: IPagedDto<IPagedCityDto>;
    isLoading: boolean;   
}

Well we need those three properties to be grouped in one property (i.e., grid) as they are related to each other. Besides, putting the isLoading outside of grid object is a cognitive load for other devs reading your code, the code would give them impression that isLoading property is related to the whole component and not specific to grid. One might say, that it can be renamed to isGridLoading to signify it pertains to the grid only.

interface IComponentState
{
    grid: IPagedDto<IPagedCityDto>;
    isGridLoading: boolean;   
}

Still the best way to write readable code is to group related things together, not just by naming convention, but through whatever the best mechanism the programming language can provide to the developer. The following is better than the code above.

interface IComponentState
{
    grid: {
        data: IPagedCityDto[];
        pages: number;
        loading: boolean;
    };
}

Better yet, use TypeScript's built-in concatenation mechanism:
interface IComponentState
{
    grid: IPagedDto<IPagedCityDto> & {
        loading: boolean;
    };
}

There's also a symmetry when grouped properties are used:

<ReactTable
    manual={true}
    columns={[
        {
            Header  : <Typography>City</Typography>,
            accessor: 'cityName',
            id      : 'City',
            Cell    : row => (
                <Typography>
                    <a href={'/city/' + row.original.cityId}>{row.value}</a>
                </Typography>
            )
        },
        {
            Header  : <Typography>State</Typography>,
            accessor: 'stateName',
            id      : 'State'
        }
    ]}
    onFetchData={this.fetchData}
    data={this.state.grid.data}
    pages={this.state.grid.pages}
    loading={this.state.grid.loading}
    defaultPageSize={10}
    className='-striped -highlight'
/>


Another nice thing when related properties are grouped together, it makes the code shorter and idiomatic when used with spread operator:

<ReactTable
    manual={true}
    columns={[
        {
            Header  : <Typography>City</Typography>,
            accessor: 'cityName',
            id      : 'City',
            Cell    : row => (
                <Typography>
                    <a href={'/city/' + row.original.cityId}>{row.value}</a>
                </Typography>
            )
        },
        {
            Header  : <Typography>State</Typography>,
            accessor: 'stateName',
            id      : 'State'
        }
    ]}
    onFetchData={this.fetchData}
    {...this.state.grid}
    defaultPageSize={10}
    className='-striped -highlight'
/>


Happy Coding!

React does not recognize the `inputRef` prop on a DOM element

With this code:
<Field
    name='locationTypeFk'
    id='locationTypeFk'
    label='Location Type'
    component={RadioGroupField}
    validate={required}
    margin='normal'
    fullWidth={true}
    required={true}
>
    {this.state.locationTypes.map(l =>
        <label key={l.id}>
            <Field
                name='locationTypeFk'
                component={RadioField}
                type='radio'
                color='primary'
                value={l.id}
            />
            <strong>{l.name}</strong>
        </label>
    )}
</Field>

I got this warning:
warning.js:33 Warning: React does not recognize the `inputRef` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `inputref` instead. If you accidentally passed it from a parent component, remove it from the DOM element.


To solve that, use <React.Fragment>, you can also use React.Fragment's shorthand, i.e., <>

<Field
    name='locationTypeFk'
    id='locationTypeFk'
    label='Location Type'
    component={RadioGroupField}
    validate={required}
    margin='normal'
    fullWidth={true}
    required={true}
>
    <>
        {this.state.locationTypes.map(l =>
            <label key={l.id}>
                <Field
                    name='locationTypeFk'
                    component={RadioField}
                    type='radio'
                    color='primary'
                    value={l.id}
                />
                <strong>{l.name}</strong>
            </label>
        )}
    </>
</Field>

React.Fragment will capture the inputRef prop instead of it being passed to label. At least that's how I understand it.


Happy Coding!

Monday, May 21, 2018

Typescript definition for process.env

// autocomplete for process.env.
declare global
{
    namespace NodeJS
    {
        // tslint:disable interface-name
        interface ProcessEnv
        {
            NODE_ENV?: 'production' | 'development';
            FACEBOOK_CLIENT_ID: string;
            FACEBOOK_CLIENT_SECRET: string;
            GOOGLE_CLIENT_ID: string;
            GOOGLE_CLIENT_SECRET: string;
            JWT_SIGNING_KEY: string;
        }
    }
}

// https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html
export {};


Happy coding!

Saturday, May 19, 2018

Redux Reducer Perfection with Immer




All of these achieves the same thing. The last one is the perfect one.

export function counterReducer(
    state: ICounterMore = {count: 0, message: 'hello'},
    action: ICounterAction
) // : ICounterMore, automatically inferred from return produce
{
    return produce(state, draft => {
        switch (action.type) {
            case CounterKind.INCREMENT:
                ++draft.count;
                break;
            case CounterKind.DECREMENT:
                --draft.count;
                draft.message = 'hey';
                break;
        }
    });
}


export const counterReducer = (
    state: ICounterMore = {count: 0, message: 'hello'},
    action: ICounterAction
) // : ICounterMore, automatically inferred from return type of produce
    => produce(state, draft =>
    {
        switch (action.type) {
            case CounterKind.INCREMENT:
                ++draft.count;
                break;
            case CounterKind.DECREMENT:
                --draft.count;
                draft.message = 'hey';
                break;
        }
    });


export const counterReducer = produce((
    draft: ICounterMore = {count: 0, message: 'hello'},
    action: ICounterAction
) // : ICounterMore, automatically inferred from return draft
=> {
    switch (action.type) {
        case CounterKind.INCREMENT:
            ++draft.count;
            break;
        case CounterKind.DECREMENT:
            --draft.count;
            draft.message = 'hey';
            break;
    }
    return draft;
});

Friday, May 18, 2018

Mutating React state

This won't work. React can't detect mutation when done this way:
interface IComponentState
{
    numberList: number[];
}

export class HomeComponent extends React.Component<ComponentProps, IComponentState>
{
    private addNumber(): void
    {
        this.state.numberList.push(Math.random());
    }
}

This works, but would have to produce immutable explicitly:
private addNumber(): void
{
    const newArray = [...this.state.numberList, Math.random()];
    this.setState({numberList: newArray});    
}


Producing immutable the convenient way, use immer:
private addNumber(): void
{
    // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-390110697

    this.setState(produce<IComponentState>(draft => {
        draft.numberList.push(Math.random());
    }));
}


Deleting an element from an array:
{this.state.numberList.map((n, i) =>
    <div key={i}>
        {n}
        <button
            // tslint:disable jsx-no-lambda
            onClick={() => {
                this.state.numberList.splice(i, 1);
            }}
        >
            Non-working delete
        </button>

        <button
            // tslint:disable jsx-no-lambda
            onClick={() => {
                this.setState({
                    numberList: [
                        ...this.state.numberList.slice(0, i),
                        ...this.state.numberList.slice(i + 1)
                    ]
                });
            }}
        >
            Delete using explicit immutable
        </button>

        <button
            // tslint:disable jsx-no-lambda
            onClick={() => {
                this.setState(produce<IComponentState>(draft => {
                    draft.numberList.splice(i, 1);
                }));
            }}
        >
            Delete the easier way
        </button>
    </div>
)}



Happy Coding!

Monday, May 14, 2018

Mutating Redux state

Mutating Redux state directly does not work.

export interface ICounterMore
{
    count: number;
    message: string;
}

export function counterReducer(
    state: ICounterMore = {count: 0, message: 'hello'},
    action: ICounterAction
): ICounterMore
{
    switch (action.type) {
        case CounterKind.INCREMENT:
            state.count = state.count + 1;
            return state;
        case CounterKind.DECREMENT:
            state.count = state.count - 1;
            state.message = 'hey';
            return state;
        default:
            return state;
    }
}


Must return new state that does not mutate the existing state.

export function counterReducer(
    state: ICounterMore = {count: 0, message: 'hello'},
    action: ICounterAction
): ICounterMore
{
    switch (action.type) {
        case CounterKind.INCREMENT:
            return {
                ...state,
                count: state.count + 1
            };
        case CounterKind.DECREMENT:
            return {
                ...state,
                count: state.count - 1,
                message: 'hey'
            };
        default:
            return state;
    }
}


Mutating Redux state "directly" works, using immer.

immer creates immutable state from the mutated state from draft, and then it return the immutable state to Redux.
Proof that immutable state is the state that is still being passed around, Redux's time travel still work.


export function counterReducer(
    state: ICounterMore = {count: 0, message: 'hello'},
    action: ICounterAction
): ICounterMore
{
    return produce(state, draft => {
        switch (action.type) {
            case CounterKind.INCREMENT:
                ++draft.count;
                break;
            case CounterKind.DECREMENT:
                --draft.count;
                draft.message = 'hey';
                break;
        }
    });
}

Happy Coding!

Sunday, May 13, 2018

Destructuring to existing variables

Can't be done like this:

function getColor(): { a: number, b: string }
{
    return { a: 0xff0000, b: "Red" };
}

let color: number;
let colorString: string;

{ a: color, b: colorString } = getColor();

window.alert(color);
window.alert(colorString);

Must be done like this, use parenthesis. As for why: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

function getColor(): { a: number, b: string }
{
    return { a: 0xff0000, b: "Red" };
}

let color: number;
let colorString: string;

({ a: color, b: colorString } = getColor());

window.alert(color);
window.alert(colorString);


Happy Coding!

Wednesday, May 2, 2018

Material UI SelectField for react-final-form

import React from "react";

import { FormControl, FormHelperText, InputLabel, Select } from "material-ui";

export const SelectField = ({
  input: { name, onChange, value, ...restInput },
  meta,
  children,
  label,
  fullWidth,
  margin,
  InputLabelProps,
  ...rest
}) => (
  <FormControl fullWidth={fullWidth} margin={margin}>
    {label && <InputLabel error={meta.error && meta.touched} {...InputLabelProps}>{label}</InputLabel>}
    <Select
      {...rest}
      name={name}
      error={meta.error && meta.touched}
      inputProps={restInput}
      value={value}
      onChange={onChange}
    >
      {children}
    </Select>
    {meta.error &&
      meta.touched && (
        <FormHelperText error={true}>{meta.error}</FormHelperText>
      )}
  </FormControl>
);


Demo code: https://codesandbox.io/s/kkp59xr047

Saturday, April 28, 2018

Session-less Facebook and Google Login with Passport using Cookie + JWT

The id and display name returned to app after logging to Facebook or Google, is encrypted with JWT and then stored to cookie. Line 74 and 77





Authenticating a page or a service is done by adding the passport-jwt middleware to a route. Line 15 and line 22.





Extraction of JWT from the cookie is done by creating a custom extractor for passport-jwt. Line 66 and 73




Full code can be downloaded from https://github.com/MichaelBuen/test-code-auth


Here's the structure of ILoggedUserJwtPayload:

import { ILoggedUser } from './ILoggedUser';

export interface ILoggedUserJwtPayload
{
    // subject
    sub: ILoggedUser;

    // expires
    exp: number;
}

This is the ILoggedUserJwtPayload sub property's structure:

export interface ILoggedUser
{
    source: string | undefined; // provider, e.g., facebook, google
    id: string | undefined; // id
    shownName: string | undefined; // displayName
}


Here's another route authenticated by passport-jwt middleware:

app.get('/api/v1/me',
    passport.authenticate('jwt', {session: false}),
    (req, res) =>
    {
        const user = req.user as ILoggedUser;

        res.json(user);
    }
);



Happy coding!

Friday, April 20, 2018

left-pad, no we're not lazy! we're just reusable!

Are javascript programmers lazy?

One criticism levelled against the javascript ecosystem is that programmers are becoming lazy with javascript. Another criticism is that a javascript function should not be a package.

There's a merit to having the individual functions have their own packages though. It adheres to Unix philosophy of "Write programs that do one thing and do it well"

And function being a package lends itself easily to be usable for scripting.

Take uuid and mkdirp package for example.

$ yarn init && yarn add uuid mkdirp


With package having only one function, uuid and mkdirp can be both API and command-line utility.


As API:




As command-line utility:



How awesome is that?


If mkdirp (rmdir, mv, cat, ...) function is part of com.acme.fileSystem package, it'll be not intuitive to make the package a commandline utility as the package covers a lot of functionalities.


Happy Coding!



yarn binaries, yarn +scripts

$ mkdir test-yarn-run && cd test-yarn-run && yarn init && yarn add jest

Yarn has a nice shortcut to run binaries in node_modules/.bin. Instead of running this:

$ ./node_modules/.bin/jest --help

Or this:

$ $(npm bin)/jest --help

Run this instead:

$ yarn jest --help


However, there's a potential ambiguity that may lead to node_modules' binaries instead of the package.json's scripts be ran with that yarn shortcut, and vice versa.

"test": "yarn jest --config jest.json",
"build": "yarn && yarn jest && yarn webpack -p"

See the potential mistake above? There's a typo on build script, instead of it running the package.json's test script, it run the jest binary in node_modules instead.

With that said, it's a good idea to have a convention that can disambiguate the package.json's scripts from the node_modules' binaries.

One good way to disambiguate them is to prefix the package.json's script with plus sign. It gives a notion that package.json's scripts are additional executables aside from the node_modules' executables.

"+test": "yarn jest --config jest.json",
"+build": "yarn && yarn +jest && yarn webpack -p"

With prefix, the command yarn +jest will immediately flag that +jest command as non-existent, as there are no binaries prefixed with plus on their name.




The plus prefix has a nicer readability for pre and post scripts too. Whereas without the prefix, pre and post scripts are harder to identify if they are part of other script:
"pretest": "yarn lint",
"prebuild": "yarn clean",
"postbuild": "yarn rimraf temp",
"test": "yarn jest --config jest.json",
"build": "yarn && yarn test && webpack -p"


With the prefix, it's immediately obvious that pre+build and post+build are related to +build, likewise with pre+test to +test.

"pre+test": "yarn +lint",
"pre+build": "yarn +clean",
"post+build": "yarn rimraf temp",
"+test": "yarn jest --config jest.json",
"+build": "yarn && yarn +test && webpack -p"


With prefx, it's easy to spot that yarn somethingHere is running a binary, instead of it running a script from the package.json. Saves the hassle of scanning the package.json to see if somethingHere is part of package.json's scripts or not.


Happy Coding!

Wednesday, April 18, 2018

Completely solve a problem with Partial


"Whenever I write code in Java I feel like I'm filling out endless forms in triplicate." -- http://funcall.blogspot.com/2010/04/whenever-i-write-code-in-java.html


In order to appease the compiler from complaining this:





I had introduced another interface just to make the properties optional:

type ActionsUsed =
    IUserAction
    | IUserCancelledAction
    | ICompanyAction
    | ICounterAction
    | IErrorModuleAction
    | ILoggedUserAction
    ;


export interface IActionsForTest
{
    counter?: {
        increment: () => void;
        decrement: () => void;
    };

    goToUser?: (userId: number) => void;
    cancelUserLoading?: () => void;

    goToCompany?: (code: string) => void;

    tellModuleError?: (error: IErrorHappened) => void;

    saveUser?: (loggedUser: ILoggedUser) => void;

    goToLogin?: () => void;
}




export interface IActionsRequired
{
    counter: {
        increment: () => void;
        decrement: () => void;
    };

    goToUser: (userId: number) => void;
    cancelUserLoading: () => void;

    goToCompany: (code: string) => void;

    tellModuleError: (error: IErrorHappened) => void;

    saveUser: (loggedUser: ILoggedUser) => void;

    goToLogin: () => void;
}


export interface IDispatches
{
    actions: IActionsRequired;
}


// Redux's built-in Dispatch can't check if a wrong value is passed to dispatch's type parameter.
// So we make our own Dispatch type.
type Dispatch<A> = (action: A) => A;

export const mapDispatchToProps = (dispatch: Dispatch<ActionsUsed>): IDispatches =>
    ({
        actions: {
            counter: {
                increment: () => dispatch({type: CounterKind.INCREMENT}),
                decrement: () => dispatch({type: CounterKind.DECREMENT})
            },

            goToUser         : (userId: number) => dispatch({type: UserActionType.USER, payload: {userId}}),
            cancelUserLoading: () => dispatch({type: UserActionType.USER_CANCELLED}),

            goToCompany: (code: string) => dispatch({type: CompanyActionType.COMPANY, payload: {code}}),

            tellModuleError: (errorHappened: IErrorHappened) => dispatch({
                type: 'ERROR_MODULE', payload: errorHappened
            }),

            saveUser: (loggedUser: ILoggedUser) =>
                dispatch({type: LoggedUserActionType.SAVE_USER_INFO, payload: loggedUser}),

            goToLogin: () => dispatch({type: Routes.LOGIN} as any)
        }
    });





So no more problems on testing:




But it looks ridiculous to write another interface just for testing.

Another way to solve the problem is to make all properties of the IActionsRequired optional by suffixing the question mark on all properties:

export interface IActionsRequired
{
    counter?: {
        increment: () => void;
        decrement: () => void;
    };

    goToUser?: (userId: number) => void;
    cancelUserLoading: () => void;

    goToCompany?: (code: string) => void;

    tellModuleError?: (error: IErrorHappened) => void;

    saveUser?: (loggedUser: ILoggedUser) => void;

    goToLogin?: () => void;
}

Testing won't require all the properties of IActionsRequired:




It would introduce compilation error when the optional property is used though:







It can be solved by using non-null assertion operator, however, it would introduce exclamation noises in the code of the consumer of the IActionsRequired, e.g.,

this.props.actions.counter!.decrement

this.props.actions.saveUser!(loggedUser)


Then I found a generic interface that makes a property of an interface optional, it would solve the problem of requiring all the properties of interface for the test object. That generic interface is called Partial. Let's restore IActionsRequired's properties as required by removing all the question marks:



And then on test, use Partial on IActionsRequired:




Partial is part of TypeScript, no need to npm install / yarn add anything, nor import Partial. Here is its definition:




Happy Coding!

Saturday, April 14, 2018

Cookie security

Testing security

app.get('/page',  (req, res) => {
    res.send(
        `
        <button type='button' id='increment'>Test</button><br/><br/>
        <button type='button' id='gcv'>Get cookie's value</button>

        <script>
        function getCookie(cname) {
            const name = cname + "=";
            const decodedCookie = decodeURIComponent(document.cookie);
            const ca = decodedCookie.split(';');

            for(let i = 0; i < ca.length; i++) {
                let c = ca[i];
                while (c.charAt(0) == ' ') {
                    c = c.substring(1);
                }

                if (c.indexOf(name) == 0) {
                  return c.substring(name.length, c.length);
                }
            }
            return "";
        }

        document.getElementById('increment').onclick = async e => {  
            // same-origin is needed for the server be able to send back the cookie
            const fr = await fetch('/renew', {credentials: 'same-origin'});
            
            const jr = await fr.json();
                
            console.log(jr); // will output 'Yay!'
        };  

        document.getElementById('gcv').onclick = async e => {    
            console.log('cookie: ' + document.cookie);
            // will not show anything due to httpOnly true
            console.log('quickBrownFox: ' + getCookie('quickBrownFox')); 
        };  
        </script>
        `);
    }
);


let n = 1;
app.get('/renew', (req, res) => {  

  // Setting httpOnly to true makes the cookie not readable from browser's javascript.
  // More secure, avoids XSS attack.

  // a non-expiring cookie. yet it gets deleted when the browser is closed though
  res.cookie('quickBrownFox', n++, {httpOnly: true});

  // persistent cookie for 7 days, stays when the browser is closed. Hmm.. that's obvious :)
  res.cookie('makulit', 'hey',  { maxAge: 1000 * 60 * 60 * 24 * 7, httpOnly: true });
  
  res.status(200).json({message: 'Yay!'});
});


app.listen(3000);


ES6 is upon us, Chrome certainly makes javascript beautiful.


Happy Coding!

JavaScript lazy-loading

function counterEager(): Iterable<number> {
    console.log('counterEager: ');

    const list = [];
    for (let i = 1; i <= 5; i++) {        
        list.push(i);
        console.log('pushed value ' + i);
    }

    console.log('counterEager ends');

    return list;
}


function* counterLazy(): Iterable<number> {
    console.log('\ncounterLazy: ');

    for (let i = 1; i <= 5; i++) {                        
        yield i;
        console.log(`resuming value ${i}`);
    }        
}


function* counterLazyMultiple(): Iterable<number> {            
    console.log('\ncounterLazyMultiple: ');
        
    const a = [100, 200, 300];            
    yield* a;
    console.log('resuming value 300');    
    yield 400;
    console.log('resuming value 400');    
    yield* a;
    console.log('resuming value 300');    
}



function* counterLazyWithMixedReturnType() {        
    console.log('\ncounterLazyWithMixedReturnType: ');

    const a = [100, 200, 300];
    yield* a;
    console.log('resuming value 300');
    yield 400;
    console.log('resuming value 400');
    yield a;
    console.log('resuming value 100, 200, 300');    
}

for (const i of counterEager()) {
    console.log('value: ' + i);    
}

let n = 1;
for (const i of counterLazy()) {
    console.log(`received value #${n++}: ${i}`);  
}

n = 1;
for (const i of counterLazyMultiple()) {
    console.log(`received value #${n++}: ${i}`);      
}

n = 1;
for (const i of counterLazyWithMixedReturnType()) {
    console.log(`received value #${n++}: ${i}`);      
}


Output:
Developers-iMac:it dev$ ts-node sample.ts 
ounterEager: 
pushed value 1
pushed value 2
pushed value 3
pushed value 4
pushed value 5
counterEager ends
value: 1
value: 2
value: 3
value: 4
value: 5

counterLazy: 
received value #1: 1
resuming value 1
received value #2: 2
resuming value 2
received value #3: 3
resuming value 3
received value #4: 4
resuming value 4
received value #5: 5
resuming value 5

counterLazyMultiple: 
received value #1: 100
received value #2: 200
received value #3: 300
resuming value 300
received value #4: 400
resuming value 400
received value #5: 100
received value #6: 200
received value #7: 300
resuming value 300

counterLazyWithMixedReturnType: 
received value #1: 100
received value #2: 200
received value #3: 300
resuming value 300
received value #4: 400
resuming value 400
received value #5: 100,200,300
resuming value 100, 200, 300


Unless you really want to yield the array itself instead of the array's individual elements, it's a good practice to explicitly indicate the return type when using TypeScript, the compiler can help you spot accidental error of yielding the array itself instead of yielding the array's individual elements:



On following, without the explicit type, the array itself (number[]) is yielded instead of its individual elements (number). Miss a single character (asterisk), the code will do different. See the output above.




It's interesting that JavaScript can yield individual elements from a list without looping by just suffixing the yield keyword with asterisk.

yield* listHere;

C# still don't have that functionality.

https://stackoverflow.com/questions/6957659/yield-multiple-ienumerables

https://stackoverflow.com/questions/5415902/c-yield-return-range-collection


And also, JavaScript syntax for generator is terser than C#. Javascript's yield elementHere vs C#'s yield return elementHere


Have C# used yield elementHere instead of yield return elementHere, yielding individual elements from an array without looping could have this syntax for C#:

yield foreach listHere;


C# team might be having a second thought to introduce syntactic sugar like this:
yield return foreach listHere;


Further reading:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function%2A

https://blog.johncrisostomo.com/basic-generators-in-javascript/



Happy Coding!

Saturday, April 7, 2018

Only Robinhood can do nested arrows, don't be so heroic

import IAllState from '../../../store/models/_i-all-state';

export interface IRootState
{
    rootState: IAllState;
}

export const mapAllStateAsRootStateToProps = (state: IAllState): IRootState => ({rootState: state});


// Following looks harder to read than the normal function
export const mapDestructuredStatesToPropsHard =
                 <T>(mapper: (rootState: IAllState) => T): (rootState: IAllState) => T & IRootState =>
                     rootState =>
                         // tslint:disable prefer-object-spread
                         Object.assign({}, {rootState}, mapper(rootState));


// Less hard than above. The exported expression is not mangled with too much types.
type IMapper = <T>(mapper: (rootState: IAllState) => T) => (rootState: IAllState) => T & IRootState;
export const mapDestructuredStatesToPropsLessHard: IMapper =
                 mapper =>
                     rootState =>
                         // tslint:disable prefer-object-spread
                         Object.assign({}, {rootState}, mapper(rootState));


// Nested arrow function looks hard, especially with TypeScript, since it's harder to decipher
// if the things that comes after the arrow is an executing code or if it is just a type.

// So despite some people going gaga over arrow functions,
// but some prefer to use normal functions when nested arrow functions mangles the readability of the code.

export function mapDestructuredStatesToProps
    <T>(mapper: (rootState: IAllState) => T): (rootState: IAllState) => T & IRootState
{
    return rootState =>
        // tslint:disable prefer-object-spread
        Object.assign({}, {rootState}, mapper(rootState));
}


Happy Coding!

Saturday, March 24, 2018

React + TypeScript + Hot-Reloading + lazy-loading a module using import and code-splitting

Plus one more thing, NodeJS.

In this post, I'll show you how to make the aforementioned technologies work.

TL;DR. Out-of-the-box, hot-reloading works, but dynamic import won't work. If dynamic import is made to work, both hot-reloading and node won't be able to work. There's a solution to these problems though.


The hot-reloading from react-hot-loader's TypeScript example is not working if code-splitting is used, though the page automatically refreshes whenever the code is changed, the whole page reloads instead of just the part that was changed, and the states reinitializes too. Even if the changes are coming from non-code-splitted code, the whole page reloads and the states gone.

Code-splitting requires setting tsconfig.json's module to esnext, and it also requires removing the babel-loader from webpack.config.js, babel-loader is used by react-hot-loader in order for hot-reloading to work.

If babel-loader is not removed from webpack.config.js's loaders, here's the error of webpack (tsconfig.json's module set esnext, target set to es6) when webpack is splitting the imports:




Here's the error if babel-loader is not removed from webpack.config.js's loaders, with tsconfig.json's module set to esnext, and target set es5:




react-hot-loader works with module set to commonjs only.


Another problem that arises from code-splitting, since it requires setting the tsconfig.json's module to esnext, codes written for node can't be run anymore. At the time of this writing (node version 8), node does not support ES modules. The only way for a TypeScript-generated code be runnable on node is by setting its tsconfig.json's module to commonjs, not esnext.

esnext might be compatible on node version 10: http://2ality.com/2017/09/native-esm-node.html

Here's the error on node when the tsconfig.json's module is set to esnext:



In order to make our TypeScript code be runnable on node, we must set the tsconfig.json's module to commonjs:



Node working: check. Node works by setting the module to commonjs.

Hot-reloading working: check. Hot-reloading is working again as tsconfig.json's module is set back to commonjs.

Lazy-loading a module using import and code-splitting: not yet working. The file theCompany.chunk.js is not splitted from index.js:




We have to find out why when tsconfig.json's module is set to esnext, webpack can split the dynamically-imported module (courtesy of await import) and in turn, emit working webpack code for lazy-loading. Here's the original code:




First, let's look at the code generated from TypeScript when the tsconfig.json's module is set to esnext. Following is the generated javascript code from the TypeScript code above.





The import statement is kept intact. Now let's apply webpack:




With tsconfig.json's module set to esnext, webpack can split the code (theCompany.chunk.js) from the code that uses await import.


When Webpack encounters dynamic import statement, Webpack replaces it with code that can dynamically import a module that works on the browser:





Now let's try setting tsconfig.json's module to commonjs, then run tsc.




Note: for ts.config that has esModuleInterop compilerOptions set to true..
"esModuleInterop": true

..TypeScript generates different code:
return [4 /*yield*/, Promise.resolve().then(function () { return tslib_1.__importStar(require(/* webpackChunkName: 'theCompany' */ '../../../front-end/Company')); })];



Hmm.. that's something different. When the module is set to commonjs, TypeScript generates Promise.resolve instead of keeping the import statement. Now let's check if webpack can apply code-splitting given the code above.



Well that's sad, the file theCompany.chunk.js is not splitted from its parent code. The file theCompany.chunk.js is not generated by webpack. Now let's take a look at the code that dynamically imports the file theCompany.chunk.js.




As the dynamic import statements is not present in the code generated by TypeScript (Promise.resolve+require is generated instead), webpack can't replace them with its own code that can dynamically-load a module from the browser, i.e.,




If we can only nudge TypeScript to keep the import statement despite the tsconfig.json's module is set to commonjs instead of it generating Promise.resolve+require, Webpack will be able to split the code afterwards. Unfortunately, there's no configuration in tsconfig.json that can keep the import statement when tsconfig.json's module is set to commonjs.


With that said, we can use webpack's string-replace-loader to revert all those generated Promise.resolve statements to dynamic import statements instead. Do an npm install or yarn add of string-replace-loader.


To cut to the chase, add the string-replace-loader to webpack.config.js's rules' loaders, then use the regex below to revert back the Promise.resolve to dynamic import statement:


use: [
    {
        loader: 'string-replace-loader',
        options: {
            search: "/\\*yield\\*/, Promise\\.resolve\\(\\)\\.then\\(function \\(\\) \\{[^r]+return require\\(([^)]+)\\);[^)]+\\)",
            replace: "/*yield*/, quickbrown($1)",
            flags: "g"
        }
    },
    'babel-loader',
    'awesome-typescript-loader'
],

Note: for ts.config that has esModuleInterop compilerOptions set to true..
"esModuleInterop": true

..use the following regular expression instead:
search: '/\\*yield\\*/, Promise\\.resolve\\(\\)\\.then\\(function \\(\\) \\{[^r]+return [^(]+\\(require\\(([^)]+)\\)\\);[^)]+\\)'


We revert Promise.resolve+require to quickbrown statement instead of dynamic import statement just to check first if our regex is correct, and check if webpack's string-replace-loader can successfully replace the Promise.resolve+require statement that was generated by TypeScript. Following is the output of the Promise.resolve+require code that was replaced by webpack's string-replace-loader:





The file theCompany.chunk.js is not splitted from index.js since Webpack cannot find any dynamic import statement from the code applied of string-replace-loader, we used quickbrown statement in string-replace-loader.




Now let's change the quickbrown statement to dynamic import statement:

use: [
    {
        loader: 'string-replace-loader',
        options: {
            search: "/\\*yield\\*/, Promise\\.resolve\\(\\)\\.then\\(function \\(\\) \\{[^r]+return require\\(([^)]+)\\);[^)]+\\)",
            replace: "/*yield*/, import($1)",
            flags: "g"
        }
    },
    'babel-loader',
    'awesome-typescript-loader'
],

Note: for ts.config that has esModuleInterop compilerOptions set to true..
"esModuleInterop": true


..use the following regular expression instead:
search: '/\\*yield\\*/, Promise\\.resolve\\(\\)\\.then\\(function \\(\\) \\{[^r]+return [^(]+\\(require\\(([^)]+)\\)\\);[^)]+\\)'


Then run webpack again:




Webpack is now able to split the file theCompany.chunk.js from index.js as it now sees the dynamic import statement.


Here's the generated code by webpack, it's the same as if the tsconfig.json's module is set to esnext:




Hot-reloading working: check.

Lazy-loading a module using import and code-splitting working: check.

Code generated from TypeScript is compatible with node: check.



This post's complete code: https://github.com/MichaelBuen/ssk-two-for-github


Happy Coding!