Tuesday, October 31, 2017

Node.js Best Practices - Async

Async function allows you to write Promise based code as if it were synchronous. It was shipped with V8 Engine since the Version 7.6.

Define a function using the async keyword, then you can use the await keyword within the function's body.
async function app () {
...
await ...
}

Async function is called, it returns with a Promise. When it returns a value, the promise gets fulfilled.

Async function throws an error, if it's rejected

Simple Async function
const util = require('util')
const {file} = require('fs')
const fileAsync = util.promisify(readFile)
async function app () {
const content = await fileAsync('log')
return content
}
app()
.then(console.log)
.catch(console.error)

If your applications are using Promise, then you can use "await" your Promises, instead of chaining them.

Above example leverage Promise using Node.js build-in "util.promisify" and read the file asynchronously.

Promise Reject/Error Handling

In the newer version of Node.js, if Promise gets rejected it will bubble down to the Node.js process. Make sure you handled the "try-catch" block properly on your app.

const util = require('util')
async function app () {
try {
await new Promise((resolve, reject) => {
reject(new Error('error'))
})
} catch (err) {
// handle the error
}
}
app()
.then(console.log)
.catch(console.error)

Tuesday, October 24, 2017

Debugging Node.js application

Debugging Node.js app is always fun, especially if you're coming from other language background such as Ruby, Python. you may looking similar debugger(binding.pry or pdb) on node js world.

In this article, let me go through how debugging node.js app with Chrome DevTool

1. Install Node.js, i use nvm
$ nvm use v8.7.0
Now using node v8.7.0 (npm v5.4.2)

2. To start debugging mode, run the Node.js app with inspect flag 
node-app $ node --inspect index.js 
Debugger listening on ws://127.0.0.1:9229/a51c84e5-78c1-481e-ac5b-ab6bc78c23fe
For help see https://nodejs.org/en/docs/inspector
Debugger attached

3. Open Chrome inspector and click on "Open dedicated DevTools for Node" to debug your app code


Now you can debug your javascript code by adding breakpoint or "debugger"











Happy debugging :)

Sunday, November 23, 2014

TextMate bundle for remove space, add newline, etc

This is one of the useful bundle for TextMate which converts Tabs to Spaces, Remove Trailing Whitespace and Add a newline at end of file https://github.com/glennr/uber-glory-tmbundle

Wednesday, August 21, 2013

Rails 4 - Scope

In rails 4, scopes should take a proc object or a block. Take an example this User model
Class User < ActiveRecord::Base
  attr_accessor :name,:age,:status

  def initialize(name, age)
    @name = name
    @age = age
  end
end
I would like to make default scope based on status 'user' and admin scope based on status 'admin'. In rails 3, I can make scope like this
#Rails 3
scope :admin, where(status: 'admin')
default_scope where(status: 'user')

Rails 4, I can make scope this way
#Rails 4
default_scope { where(status: 'user') } #  block
#default_scope ->{ where(status: 'admin) } #Proc valid
scope :admin, ->{ where(status: 'admin') }
If we try to use scope without(see rails3 examples) passing proc or block in Rails 4, it triggers DEPRECATION WARNING message.

Rails 4 - Finders

Old-Style finders are deprecated
In Rails 4, Old-Style finders are deprecated. Consider User model with name, age members
Class User < ActiveRecord::Base
  attr_accessor :name,:age

  def initialize(name, age)
    @name = name
    @age = age
  end
end

In this class, If we want find user with name of 'foo'. See the difference in rails 3 and rails 4 call
#Rails 3
User.find(:all, conditions: { name: 'foo' })
#Rails 4
User.where(name: 'foo')

In rails 4, you will get DEPRECATION WARNING: Calling #find(:all) is deprecated. You can call #all directly instead or build a scope instead of using finder options.

Dynamic finders that return collections are deprecated
#Rails 3
User.find_all_by_name('foo')
#Rails 4
User.where(name: 'foo')

In Rails 4 alerts DEPRECATION WARNING if we use dynamic method(User.find_all_by_name). Preferable alternative option is User.where(...).all