Convenient Ways to Print Out Entire Objects in JavaScript

Quick debugging in JavaScript often requires one to print out or log a full object to see what values it contains.

The usual console log can often print “[Object object]”, which is not useful.

Some convenient ways to see the entire object in logs are below.

Using the %o format specifier, which means “formatted as an object”:

console.log("%o", myObject)

Using the dir function:

console.dir(myObject)

The “dir” in console.dir() comes from “directory”, as in a directory of all the properties of the object. This always outputs a full hierarchical representation of the object.

Another way is to fully serialize the object into a JSON string:

console.log(JSON.stringify(myObject))

This is very useful especially in the context of loggers, so if logger is an instance of a logging object (such as a Winston logger), then we can log a complete JSON object using:

logger.info(JSON.stringify(myObject))

The Fields Pattern in REST API Design

The Fields Pattern or Field Selection Pattern for REST API design is a useful approach whenever the representations returned from the API become quite large and the API can be used by many clients in different contexts. For example, a native app client may only require a select few fields from the usual resource representation.

Suppose we have a resource employees, with employee representations containing a large number of fields. With the fields pattern, a client could make a request of the form:

GET /employees?fields=name,role,salary

The API will respond to this request with only these fields in addition to id:

{
   "id": "12345",
   "name": "John Smith",
   "role": "Developer",
   "salary": "100,000K"
}

A different client can request a different selection of fields:

GET /employees?fields=projectId,address
{
   "id": "12345",
   "projectId": "6789",
   "address": {
      "streetName": "REST Avenue",
      "postalCode": "J6V 9M2",
      "city": "Toronto"
   }
}

It is also possible to omit the id field, though arguably a resource representation should always have its primary identifier present, even when selecting fields.

If the fields parameter is omitted, the API responds with all fields of the employee resource available.

What if we want to be able to select fields of sub-objects, such as the address object? There are several options, for example:

GET /employees?fields=address:city

GET /employees?fields=address.city

GET /employees?addressFields=city

However, none of these are fully satisfying and venture into inventing syntax. Almost certainly, no two API designs will select the same syntax, and so none of these are ideal for a natural, simple design.

Selection of fields on arbitrarily complex objects is one of the many elegant, standard solutions provided by GraphQL, so a GraphQL API design may be preferable in cases where complex multi-level field selection is desired.

apiVersion field missing error in OpenShift

If you are running into the following error message in OpenShift when processing a YAML template:

error: unable to get type info from the object “*unstructured.Unstructured”: Object ‘apiVersion’ is missing in ‘object has no apiVersion field’

The cause is a problem with the apiVersion field in the template — even if it is present; the error message is misleading.

  ...
-kind: ImageStream
  apiVersion: 1 # Incorrect, must be v1
  metadata: 
    ....

The apiVersion value must be v1 instead of 1.

 

bash Version Differences in Mac OS X

Beware of differences in Mac OS shell commands executed by /bin/bash and /bin/sh.

These are not the same shell, despite the version output (example on Mac OS High Sierra). The version output is identical as shown below:

>/bin/sh --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Copyright (C) 2007 Free Software Foundation, Inc.
>/bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)

Yet, the behaviour of these two binaries differs, for example in the echo command:

>/bin/sh
sh-3.2$ echo -n "test"
-n test
sh-3.2$
>/bin/bash
bash-3.2$ echo -n "test"
testbash-3.2$

Note that echo in /bin/sh does not recognize “-n” and simply outputs the string, while /bin/bash recognizes the switch to mean omit newline.

Recursive Anonymous Functions in JavaScript

It is possible to create recursive anonymous functions in JavaScript.

Usually we need a name for a function to recursively refer to itself, but since anonymous functions have no name, JavaScript provides arguments.callee as a way to refer to the function that called the function we are currently executing!

First, here is a regular factorial function using its name to refer to itself:

var fact = function(n) {
  if (n === 0) {
    return 1;
  } else {
    return n * (fact(n - 1));
  }
}

We can replace that name reference with arguments.callee:

var fact = function(n) {
  if (n === 0) {
    return 1;
  } else {
    return n * (arguments.callee(n - 1));
  }
}

In this way, we can use recursive functions without ever giving them a name!

In the following code we print out the factorial of 5 computed with an anonymous function, never giving it a name:

console.log(
  (function(n) {
    if (n === 0) {
      return 1;
    } else {
      return n * (arguments.callee(n - 1));
    }
  })(5)
);

See these important notes about this feature of JavaScript:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee

GraphQL Terminology

The following is a glossary of common terms and definitions used in GraphQL.

Fragment

A group of fields specified together (on the client) which can be used in many places in one query or in several queries. For example: name, ID and address could be grouped together in a fragment called EmployeeInfo, and this fragment can be used to request this group of fields in several places in a query.

Inline Fragment

Inline Fragments are elements of queries used to request fields of a Union Type or an Interface Type. Suppose we have a type Thing which is a union of Book and Car – if we want to query a list of Things, we might want to get titles for books and brands for cars, which are fields that only make sense for these individual types respectively. So with inline fragments we can write something like this:
{  
   allThings {
      ... on Book {
         title 
      }
      ... on Car {
         brand
      }
}

Root Type

Root types are GraphQL types which allow us to reach all the other types: they are the starting points for queries and appear as the entry points to explore from in the GraphiQL explorer. There are three root types: Query, Mutation, Subscription. For example, we can reach all of the specific query types possible from the root type called Query.

Union Type

A union type or simply union in GraphQL is a type made up of several other types. For example, we can define a type Pet to be a union of Cat and Dog. This would mean that Pet type objects can be either Cat or Dog objects, with potentially different fields. The syntax is:

union Pet = Cat | Dog

 

Indicating deprecation of a field in a GraphQL Schema

The GraphQL Schema Language provides a very handy feature to indicate that a field has been deprecated. This will show as a prominent text box on auto-complete in the query builder in GraphiQL, as well as in the documentation explorer. This is a great way to indicate to developers using your GraphQL API that code using a field should  ideally be changed. The reason for deprecation can be included as an annotation right in the schema itself!

In the following schema, we have indicated that the field topic is deprecated for the Book type:

type Book {
   id: Int!,
   title: String,
   topic: String @deprecated (reason: "Field is no longer needed")
}

When we explore the schema with GraphiQL, the deprecation message will display when viewing the field.

The best way to install the latest Node.js on Ubuntu

There are many ways to install Node, but for the latest version you cannot use apt install or apt-get install.

The best way is to use the Node Version Manager (nvm) to install Node.

Note that there is no Ubuntu package for nvm and nvm is not a regular binary, but rather a shell function.

Note also that nvm is not meant to be used with sudo ! The install will be for your current regular user.

Before installing: make sure to have a .bash_profile file in your home directory.

The following steps will install nvm and node (and hence npm).

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash

Reload your terminal.

Find the latest version listed by the following command:

nvm ls-remote

At the time of writing the latest was 9.5.0, so:

nvm install 9.5.0

nvm use 9.5.0

Check that the latest versions of node and npm are ready:

node -v

npm -v

Installing and Running PostGraphQL

PostGraphQL will provide GraphQL access automatically to your data stored in a PostgreSQL database.

Assuming we have PostgreSQL installed already with at least one database created but we don’t have Node yet – install Node Version Manager (nvm), the latest version of Node.js and PostGraphQL:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash

nvm install node 

npm install -g postgraphql

Assuming we have a database called my_database and a user my_database_usr, in one terminal run the PostGraphQL server:

postgraphql -c "postgres://my_database_usr:password@localhost:5432/my_database"

The server should be running on port 5000 on localhost.

Note: make sure you have a PostgreSQL version newer than 9.4 or else you will see this error:

error: function pg_catalog.pg_relation_is_updatable(oid, boolean) does not exist

In another terminal, send an HTTP POST request to see what data is available:

curl -X POST "http://localhost:5000/graphql" -H "Content-type: application/json" -d "{\"query\": \"{__schema{types{name}}}\"}"

The following example query assumes a table “books” with a field “title” in my_database. The cURL command is below:

curl -X POST "http://localhost:5000/graphql" -H "Content-type: application/json" -d "{\"query\": \"{allBooks{edges{node{title}}}}\"}"

In a browser you can also explore the data with GraphiQL at:

http://localhost:5000/graphiql

 

Vim Command List

A list of useful vim (vi) editing commands.

 

cc

Replace entire line: delete and enter input mode.

:r filename

Paste contents of filename into current file.

:x

Write file and exit. Short for :wq