How does sequelize pluralize?

If you use .sync with sequlize and have a model name like User, your database ends up with a table called Users. More clearly, when you use the sequelize-cli model generator the generated file will show this pluralized table. Here is the code: (link)

What is Utils

* Note Sequelize has a directory called Utils AND a file at lib/utils.js.

What’s in lib/util.js?

 

We find the function! This is how sequelize defines utils.pluralize link

Util.pluralize IS inflection.pluralize

This is how its tested 

What is inflection?

Inflection is a port of Ruby on Rails Active Support Inflection classes into JavaScript built by DreamersLab in Taipei. (link)

So how does sequelize/inflection pluralize?

Inflection seems to have rules based on:

Eventually, inflection takes these rules, uses RegExp and applies them to your string. Theres a bunch of rules and at the end theres this

The common rule that is the exhausted else or case default rule that targets the end of the string with $. No rules for that singular term? Add an s

Postgres timestamp with timezone – “timestamptz”

Postgres can store your timestamp WITH or WITHOUT timezone.
If you don’t specify either, it will default to “timestamp without timezone”

Which one should you use? TLDR: “timestamps with time zones”

Whats the problem living life without timezones?

Say you have two users in two different timezones – one in California and one in France. Imagine you may need to know which one acted “first”, maybe in an auction or draft scenario where the whoever acts first wins.

Without specifying timezone, your database will save the plain timestamp of each user, say “midnight” and “midnight”. How will you know which one acted first?

You could save the original timezone from the user and perform the necessary algebra when needed.

Solution – Use “timestamp with time zone” otherwise known as “timestamptz” 

For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system’s TimeZone parameter, and is converted to UTC using the offset for the timezone zone.

Postgres docs

This bears repeating: 

“For timestamp with time zone, the internally stored value is always in UTC.”

A proper name for this might be timestamp saved as UTC by default. By saving everything in the “same” timezone, we know the absolute time of the timestamps.

This brings up the main UX concern: What do users see?

Your users want to read data from the database using their preferred timezone.

(If they added a blog post at 3:00pm PST, they want to see the timestamp as 3:00pm not, )

Dates are saved as UTC so you will eventually need to convert the time

Converting on the server:

Best practice is to save the users’ preferred timezone as a name (e.g. America/Los_Angeles). This way your query or ORM can convert the date according to user preference.

Remember, timezones offsets are affected by political actions. A timezones actual hour offset can change depending on whether the timezone recognizes daylight savings time or just simply when the political “owners” of the timezone decide to CHANGE the offset. Read The Long, Painful History of Time for more info.

Converting on the browser:

Many browsers have default timezones that can be used by passing in your date to new Date. You can also, simply use moment.js to parse the dates on the client to show the correctly formatted date string for your purpose.

What about user input?

User input should always be converted to UTC. Many functions already return UTC by default such as  new Date() in Browser JavaScript and node.

 

Resources:

PostgreSQL Data Types: Date, Timestamp, and Time Zones

Detecting the time zone from the browser: 

Using CAShapeLayer to draw a circle

UIViews are like Ogres, which are like onions – they have layers.

Source: Documentation

More accurately, UIView has a single layer property that can have infinite sublayers.

UIView’s have layers

Lets draw a circle.

First create a UIView and a CAShapeLayer:

let myView = UIView()

let myLayer = CAShapeLayer()

Layers have a path

UIBezierPath makes drawing shapes extremely smooth, lets say in the shape of a circle:

let circlePath = UIBezierPath(
  arcCenter: CGPoint(x: 100.0, y: 100.0),
  radius: 100,
  startAngle: 0 * CGFloat.pi / 180,
  endAngle: 360 * CGFloat.pi / 180,
  clockwise: true)

Great! Now we can add CAShapeLayer as a CGPath and spruce up our fill and stroke colors

myLayer.path = circlePath.cgPath
myLayer.strokeColor = UIColor.blue.cgColor
myLayer.fillColor = UIColor.yellow.cgColor

Last step! Add this layer to your UIView

myView.layer.addSublayer(myLayer)

Layers have attributes

strokeColor,fillColor, opacity, lineWidth and more!

Bonus: Layers can animate attributes

// create the animation
let opacityAnimation = CABasicAnimation(
  keyPath: #keyPath(CALayer.opacity))
opacityAnimation.fromValue = 0
opacityAnimation.toValue = 1
opacityAnimation.duration = 5.0

// set the final value; add the animation
myLayer.opacity = 1
myLayer.add(opacityAnimation, forKey: #keyPath(CALayer.opacity))

iOS Application Lifecycle – UIKit basics

iOS applications are all about cycles

This is because the iOS applications are richly interactive when it comes to user input and much of your programming with UIKit will be delegate oriented. Knowing the many different “cycles” of the device and application will be illuminating for your development.

States of the UIKit App Cycle

* These are the execution states of a UIKit app from the Apple docs. But why so many arrows? Below is the simplified flow charts

User Action: Your app has not been launched

Your application starts off Current State: Not Running

User Action: Your app is launched

Delegate method called: application(_:didFinishLaunchingWithOptions:)

New state: Inactive – your application is briefly here as it prepares a successful launch

New state: Active – your application is now the “foreground app”.

Many apps will place a majority of the app setup logic in this function including setting up a programmatic view controller setup (bypassing the default storyboard)

Delegate method called: applicationDidBecomeActive

User Action: User goes to home screen or opens another app

 

Current state: Active

Delegate method called: applicationWillResignActive

New state: Inactive – your application is briefly here

New state: Background – your app is available in the app picker screen on home button double tap

Delegate method called: applicationDidEnterBackground*

* If your app does not support background execution “applicationWillTerminate” is called

** If your iOS device is low on memory, it may suspend and even terminate your app back to the state “Not Running”

User Action: User reopens a background app

Current state: Background

Delegate method called: applicationWillEnterForeground

New state: Active

Delegate method called: applicationDidBecomeActive

 

TLDR: Your basic UIKit flow moves from Active <-> Background

These are only the basic lifecycle events for your UIKit app, there are MANY different scenarios that can change the state of your app – the device can span a low battery warning and show the power saving alert, a phone call may occur, users can click and hold notifications, the device can run out of batteries.

iOS without storyboard

Why?

Programmatically/Code or NIB based layouts are a much better fit for projects that use version control (see merge conflicts) and make it much easier to reuse views. If you are deciding not to use storyboards, you will need to manually set your application window to your desired UIWindow

Prerequisites:

– Delete Main Interface from Deployment Info Settings

– Delete the Main.storyboard file

How to: set up a iOS project without storyboard

Step 1: Create a UIWindow with the frame using the bounds of the UIScreen

UIWindow(frame: UIScreen.main.bounds)

Step 2: Assign this to the AppDelegate window property

window = ...

Step 3: Make the window “key” and “visible” 

window?.makeKeyAndVisible

Step 4: Set the window `rootViewController` to the VC of your choice

window?.rootViewController = ...

Code: link

Forgetting to set translatesAutoresizingMaskIntoConstraints to false

UIKit on iOS is great! There are tons of tools and often this can supercharge your productivity for getting a prototype out into the world.

Additionally, working with AutoLayout programmatically can be great if you avoid these rookie mistakes.

Rookie Mistake 1:

It hurts when you spend hours dealing with the rookie mistake of forgetting to set translatesAutoresizingMaskIntoConstraints to false on the view when setting constraints.

view.translatesAutoresizingMaskIntoConstraints = false

Rookie Mistake 2: 

Remember that you also have to also set your NSLayoutConstraint to true

Example:

yourView.centerXAnchor.constraint(equalTo:
  view.centerXAnchor).isActive = true

Solution:

This function allows you to program with wild abandon! If you use this function to set your constraints you never need to remember those pesky settings.

func setLayoutConstraints(
    view: UIView,
    constraints: [NSLayoutConstraint]) {
        view.translatesAutoresizingMaskIntoConstraints = false
        constraints.forEach({constraint in
            constraint.isActive = true
        })
}

Code found here, and more

*Update: Apple created a convenience method on NSLayoutConstraint called .activate that will set the isActive property to true. The new code would look like this:

func setLayoutConstraints(
    view: UIView,
    constraints: [NSLayoutConstraint]) {
        view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate(constraints)
}

Delete files by filename with “find”

When you upload photos multiple times, the computer can start numbering the photos. IMG_A becomes IMG_A 1 and IMG_A 2 and IMG_A 3.

Using a wildcard * and specifying the ending space and number will help you select the files. For example:

Find all the files that end in "space"1.JPG

find -name '* 1.JPG'

* Have a look at the returned files to make sure you want to delete these

Find AND DELETE all the files that end in "space"1.JPG

find -name '* 1.JPG' -delete

gist

Setting environment variables

How to see and set your environment variables

Print all your current environment variables with 

$ printenv

See a the value for a specific variable with echo

$ printenv <YOUR_VARIABLE> or $ echo $<YOUR_VARIABLE>

For example:

$ printenv MY_API_KEY or $ echo $MY_API_KEY

How do I set the variable temporarily?

This will set your variable for ONLY your current shell session

$ export <YOUR_VARIABLE>=some-secret-pattern

You can also prepend values to a currently set variable

$ export <YOUR_VARIABLE>=some-secret-pattern:$<YOUR_VARIABLE>

This is why you see export PATH statements like this

export PATH=/usr/local/mysql/bin:$PATH

This is actually prepending /usr/local/mysql/bin to the existing PATH

How do I set the variable permanently?

You can run the same start up export command with every shell session if you put this in your .bash_profile

export <YOUR_VARIABLE>=some-secret-pattern

* Make sure you source your bash_profile to see the changes

$ source ~/.bash_profile

How do I see it in my code?

Using your node shell:

node> console.log(process.env)

Using your python shell

python> import os; print os.environ

Postgres tutorial – installing with brew + basics

Step 1: Install postgres

brew install postgres

Step 2: Start postgres server

brew services start postgresql

Step 3: Create a database

Lets call our database “book”

$ createdb book

Step 4: open the psql shell

List all databases in terminal with: $ psql --list

Adding the name of the db after the command psql will open the shell to that db

$ psql book

Your psql shell has different command. For the rest of the article, we will be using the psql shell.

List your databases in psql shell with: \l

* When checking the docs make sure you check know your postgres version with: select version();

Step 5: Create a new table

list your current database tables with: \dt

Create format:

CREATE TABLE <table_name> (<field_name>, <field_type>);

Lets create fields for “body”, “date” and “code”:

CREATE TABLE dids (body text, date timestamp, code text);

Inspect your table schema with: \d <table_name>, e.g. \d dids

Step 6: Add some table rows

Remember: SINGLE QUOTES ONLY and remember the ending semi colon

INSERT INTO dids (body, date)

  VALUES ('paired with Corey', NOW());

INSERT INTO dids (body, date)

  VALUES ('remembered that SQL is SINGLE QUOTES ONLY', NOW());

 

OOPS… – we realize here that our table does not have a primary key

Step 7: Alter your table columns (Schema migration)

Your tables will likely evolve throughout time – you may want to add fields to you table, or like above, we forget to add a primary key.

Add a column for “primary key” that auto increments

ALTER TABLE dids ADD COLUMN id serial primary key;

look at the table schema with: \d <table_name>

Step 8: Query your new database!

select * from dids

 

Installed with:

Homebrew 1.7.1

postgres (PostgreSQL) 10.4

Heroku: Node, Express, PostgreSQL Setup

Step 0: Have an app

Create an empty app if you dont have one

Create a folder, cd into it and initialize your git repo.

$ mkdir <app_name>; cd <app_name>; git init

Step 1: Install Heroku

Install the heroku cli with homebrew

$ brew install heroku/brew/heroku

Check your heroku installation and login if necessary: 

$ heroku --version

Note: heroku will check for the latest version every* time you run the command

$ heroku login

or $ heroku login -i to stay in your CLI

Check what apps you have already created:

$ heroku apps

Step 2: Create a new named heroku app

$ heroku create <app_name>

If you run this command with the <app_name> heroku will choose a new random name for you.

In the picture above, https://theptrk.herokuapp.com is the new url for your blank app.

* this is the default site for your new app that sends a 502 HTTP code

Check that your app has been created

$ heroku apps

Step 3: Initialize your app to your heroku git url*

* If you ran heroku create in your app directly this step will be done automatically.

Check this by checking for a remote named heroku

$ git remote -v

If you dont see heroku, continue with this step.

“””With Github you might be used to using the word origin to mean your Github url, but the convention for heroku is to name this remote “heroku”. Note that this remote name is completely arbitrary and has nothing to do with the platform or url or anything.”””

Use git remote --verbose to check if you have any remote urls set up. There should be none

Get your apps “info” with info

$ heroku info <app_name>

With your git url add your remote:

$ git remote add heroku <git_url>

$ git push --set-upstream heroku master

* Notice that once you set this and push, you no longer need to specify the --app=<app_name>

** Note that heroku commands return different things depending on where you are.

 

Step 4: Set up node.js, install express.js

Create a package.json 

This file will be used by node/npm to indicate meta data, dependencies and other project level info

$ npm init

Install express.js

$ npm install express --save

Set the node version package.json to the one on your local machine.

You can check your local version with $ node --version

"engines": {
   // use your local version to stay consistent
   // if you want to push a newer node version, update your local node version
   // use nvm for the best way to handle local node versions
  "node": "10.6.0"
},

Create a “start” script

This is the script which is run whenever the command npm start is run.

Heroku will use this “start’ script as the default script if no Procfile is found.

"scripts": {
  "start": "node index.js"
}

curl express hello world (link)

curl -L https://bit.ly/express-hello-world > index.js

Run this server locally with 

$ heroku local web or $ npm start

Check out your website at http://localhost:5000/

At this point, you can git push heroku master

Step 5: Installing PostgreSQL instance for your app

Postgres instances are created and assigned to individual apps as “add-ons”.

Use this command to see all your existing add-ons.

$ heroku addons

** Note that heroku addons performs differently depending on where you are. If heroku recognizes that you are in a heroku app, it will only show you the add-ons for only that app. cd to a directory that is not a heroku app (say your home directory) and heroku will show you all add-ons for your account.

Create your PostgreSQL instance:

$ heroku addons:create heroku-postgresql:hobby-dev --app=<app_name>

Get more info with: $ heroku pg:info*

* if you navigated to a different directory, you may need to specify the app like this heroku pg:info --app theptrk

Congrats! You now have a heroku app instance and PostgreSQL instance.

Connecting to your PostgreSQL instance:

If you want to connect your app to your db, note that heroku automatically created a DATABASE_URL config variable for you. Type heroku config to see your current config variables. You can access this variable with process.env.DATABASE_URL in your application code.

Updated: added heroku login command; Mark Lewin suggested