Categories
Javascript

Save time: npm install nodemon

Nodemon will allow you to start your node.js project and make changes without manually shutting down and restarting your server.

Many people are scared of installing nodemon globally, so here’s a guide to install nodemon locally in your node.js project.

Step 1: Install nodemon 

$ npm install nodemon --save

Step 2: Update your npm scripts object in package.json

"scripts": {

    ...

    "start": "nodemon index.js

}

Note: If you used the express generator you will change "nodemon index.js" to your entry point into your server, which is likely “nodemon ./bin/www"

Step 3: Run your new npm script

$ npm start

Congrats!

Now our JavaScript changes will restart your server automatically

* Note, many frameworks compile and cache templates so changing your html/jade files may not restart your server.

Categories
Javascript

Setting up Redis on Heroku for ExpressJS

By default, your express application will store session data in memory. That means if your server restarts all users will need to log back in. Additionally, this does not scale to more than one instance, leaks memory and does other mean things. While this works while developing your local computer (notice how you always need to log in after making a code change), you will want something better for production.

Heroku even warns you if you do this. Try running $ heroku logs --tail to see this.

Welcome Redis

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.

Step 1: Create the heroku add on

$ heroku addons:create heroku-redis:hobby-dev

This will create a REDIS_URL in the heroku config that you will use to connect. Use $ heroku config:get REDIS_URL to see this value.

Step 2: Download the connect-redis package for your project

$ npm install -s connect-redis

Step 3: Pass in express-session into connect-redis

Step 4: Create an instance of RedisStore as the store property of your session configuration

Note: your local computer probably does not have REDIS_URL set.

Step 5: Push to heroku and try your new session store

$ git push heroku master

How do you run your project locally now?

Option 1: default to memory session store locally

Check your NODE_ENV setting and if its not production we will default the store property to null.

Option 2: default to using a redis instance locally

Run these commands and connect to your instance directly.

Screen Shot 2019-04-07 at 2.51.07 PM.png

Gotcha Error: req.flash() requires sessions

If you try running your project locally, you will notice that your session store fails to initialize and things break – this happens since you likely do not have the REDIS_URL set.

Production ready: 

Note that redis on hobby dev will not allow SSL and to secure a production redis, you will need to pay for a production plan and add “stunnel” to your buildpack. (link)

Categories
Javascript

Create an interactive terminal cli with node

Let’s create a tool that will track our some text entries.

Step 1: Create a new npm project and install the necessary libraries

$ mkdir my_cli && cd my_cli && npm init -y && npm i --save inquirer chalk

chalk – helps color the terminal prompts

inquirer – makes creating interactive prompts a breeze

Step 2: create interactive terminal prompts

Step 3: save or append to a file (did.txt)

Full code here

Categories
Javascript

How to publish an npm module

Step 0: You need some code to share.

Create a new Github repo or choose one you currently want to publish

Here is the command line argument to create a repo called “adder”

$ curl -u <your_username> https://api.github.com/user/repos -d "{\"name\": \"adder\"}"

Once you have chosen a Github repo clone it

Step 1: Create a proper package.json

The best way to do this is to run the npm init command

$ npm init

This will insure you have the required package.json file with name and version set.

Step 2: Publish

$ npm publish

If you are not logged in, you will need to run npm login

Thats it!

Step 3: Test your npm package

Double check your package information with $ npm info <package_name>

Alternatively, go to another repo and run $ npm install <package_name>

Congrats! Your code is out in the wild on the npm registry 🙂

Troubleshooting: Package name already exists

You might run into the issue where someone else has taken the name of your npm package. Note that you can set a different name on npm than your github repo. One option is get super creative with your npm package name and change the “name” key in package.json. Another option is to namespace your package to your username like this:

"name": @theptrk/express 

and then publishing this with the public flag

$ npm publish --access=public

What if I want to publish a new version?

npm will reject your package if you do not bump the version number. Use npm version and choose either major, minor, or patch. This is the example for patch

$ npm version {major, minor, patch}

$ npm publish

Categories
Javascript

Do not use bcrypt-nodejs

“Invalid salt revision”

bcrypt-nodejs is no longer maintained and you might run into this

Use bcryptjs for a more secure actively maintained experience.

Also, check out Django, its great, but if you do, consider adding bcrypt

 

Categories
express

Express Sequelize Heroku Postgres Configuration Success

You are in flow developing on your local database and you decide to upload everything to heroku and share it with the world.

How do you configure your production database?

It’s easier than you think. Let’s assume you have already set up your site.

If you used the sequelize init command, you will have a file db/models/index.js that looks like this

Usually, your sequelize database will initialize with the usual database, username password, etc but in the special case that your config has use_env_variable, sequelize will recognize that an environment variable (usually representing a URI) can be used in place of the usual credentials.

What is your env/config variable?

Find your heroku config variables in the heroku website or by running $ heroku config. Note, config and env variables are used to reference the same settings here.

When you create a database on your heroku account, it will default a new configuration setting called “DATABASE_URL”

You can access this with process.env.DATABASE_URL in any of your node.js code (on production). Your local machine will have different environment variables set.

Step 1: Set use_env_variable

But set it to what? Set it what heroku designates as your database url, DATABASE_URL!

Thats it!

You may need to migrate your database if you aren’t using sync

Step 2: Migrate your database

Simply run the migrate command in the heroku environment with heroku run. This avoids any configuration errors of running from your local environment

$ heroku run ./node_modules/.bin/sequelize db:migrate --debug

Final config

Step 3: Check your database

Run the heroku psql command and run the “list tables” command.

$ heroku psql

$<app_name>::DATABASE=> \dt

Possible Errors

Error: no pg_hba.conf entry for host…, SSL OFF

Add the ssl setting into dialectOptions of your config.json

Error: The server does not support SSL connections

This may be an outdated error. But previously, users who tried to migrate on their local computer would run into this error.

$ NODE_ENV=production DATABASEURL=$(heroku config:get DATABASE_URL) ./node_modules/.bin/sequelize db:migrate

This will not work correctly unless you set up your local computer to support ssl in the migration. You could get a certificate and configure your sequelize config to use that BUT theres an easier way.

ERROR: SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:5432

It’s quite possible you forgot to push your code to heroku. Make sure you git push heroku master!!!

Categories
Coding Javascript

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

Categories
express Javascript

curl express hello world

The official express.js hello world example may crash on certain deployments that rely on a certain PORT.

Make sure you use the PORT set on process.env if it is set.

const PORT = process.env.PORT || 3000

Complete example (code):

const express = require('express')
const app = express()
const PORT = process.env.PORT || 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(PORT, () => console.log(`Example app listening on port ${PORT}!`))

Expert level: How to curl this into an index.js file

I’ve created a bit.ly link that links to the raw version of a file called “hello-world” in my repo “code

How to: curl it and create an index.js file

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

 


More about curl

Categories
Browser API Javascript

How to detect if a user is online

Many browsers have implemented events “online” and “offline”; in addition to this, browsers also expose the navigator.onLine property that will return “online” or “offline”

How many browsers is many?

caniuse says every major browser (Chrome, Firefox, Safair, IE11…) except Opera mini has this functionality (as of July 4th 2018).

How can I check the online status?

> navigator.onLine

How can I listen to events?

BE LOUD

Be loud if core functionality depends on staying online

If your app depends on autosaving,

BE LOUD ABOUT NOT BEING ABLE TO SAVE.

Be like workflowy*. Tell the users, make them listen.

Caveats

You will likely need more error handling than this. For example: what if your server is offline? what if the request body has malformed? what if the server is up but your database is down? what if the api hits a 404 and do you let your devs know about this?

* referral link

Categories
Javascript

This post is not about Backbone

We’re gonna talk about video games.

Imagine you’re playing Mario Kart on a four person split screen. There are four Yoshis on the screen for each player. How many Yoshis should we model?

The obvious answer is four: there are four Yoshis on the screen, so there must be four Yoshis. The problem is that this answer misses something important, and fails to answer a critical question: what if there were no Yoshis on anyone’s screen right now? Does that mean there should be zero Yoshis? No, of course not, Yoshi can fall behind in the race and should still exist.

The real answer is there is only one Yoshi – one source of truth that dictates where Yoshi is, how fast he’s going, what items he has, and what he’s about to do. Fundamentally, all this means is that Yoshi exists separate from his representation to the user. We can organize our code to represent this by grouping our data about Yoshi in a single location.

Mario Kart on Super Nintendo
Mario Kart on Super Nintendo

 

Models as the source of truth

Models are used to encapsulate data. A Model stores data properties and serves as the ultimate reference in other parts of our game. In our example Yoshi, Mario, Bowser are all Models – they have a single state and source of truth that’s associated with them. With this distinction we avoid searching for information on multiple Yoshis or creating logic to determine which copy of Yoshi is the most updated version of our racer.

Models are isolated from the code that displays the screen to the user so while Yoshi may turn a corner and disappear from the screen, our game logic continues figuring out how fast and far Yoshi has gone. We decide what to show users through building Views.

 

Views as Lakitu

160px-Lakitu_-_Mario_Kart_8
Imagine all the Lakitus filming the race

Views decide what to show the user. Each View is associated with a model, and decides exactly how that model should be shown on screen. We wouldn’t want to just show the user all the stats about Yoshi, we want to make it a cute green dinosaur in a cart that you can see and aim at – View’s make that happen.

You can have lots of Views for a single model. For instance, even though there’s one Yoshi there’s actually up to four Views associated with him! In regards to Views, four is actually the right answer. Our Model for Yoshi has only one location and one speed, but our View shows him in four different places on each screen and renders him going in different directions depending on where you 

If we began to store information about Yoshi in the graphic, we run the risk of creating data inconsistent with our original source of truth. What if there are multiple Yoshi graphics? By separating the storage of data from the representation of data we ensure that all players see the same Yoshi.

Events as a Blue Shell

When Bowser grabs a blue shell and throws it, this is a global event that every racer wants to know about. A smart group of Views will have event listeners on its respective Models. Smart Views can listen to events from the Model such as a ‘change’ or ‘add’ event. As our Models pass these event notifications to our Views, the screen responds by showing the player a blue shell rushing towards first place.

Our method of drawing data becomes increasingly more important as we add online players to the race from Mario Karts game servers. Having one source of data ensures that every player has a uniform experience. As there is only one Yoshi, there should only be one tweet, wall post and chat message that our Views are listening to.

Libraries and Frameworks

Concise code lends itself to become more reusable and testable. Our clear sense of separation and organization allows us to write modular code that is focused on clearly defined tasks. Every library and framework implements this differently and it will take some exploring to find the right fit.