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