# 3.2. JavaScript

Note

While every design function has access to all JavaScript objects, the table below describes appropriate usage cases. For example, you may use `emit()` in Map Functions, but `getRow()` is not permitted during Map Functions.

JS Function | Reasonable to use in design doc functions
--- | ---
`emit()` | Map Functions
`getRow()` | List Functions
`JSON` | any
`isArray()` | any
`log()` | any
`provides()` | Show Functions, List Functions
`registerType()` | Show Functions, List Functions
`require()` | any, except Reduce and Rereduce Functions
`send()` | List Functions
`start()` | List Functions
`sum()` | any
`toJSON()` | any

## 3.2.1. Design functions context

Each design function executes in a special context of predefined objects, modules and functions:

emit(key, value)

  Emits a key-value pair for further processing by CouchDB after the map function is done.

  Arguments:

    - key – The view key

    - value – The key’s associated value

      function(doc){
          emit(doc._id, doc._rev);
      }

getRow()

  Extracts the next row from a related view result.

  Returns:

    View result row

  Return type:

    object

      function(head, req){
          send('[');
          row = getRow();
          if (row){
              send(toJSON(row));
              while(row = getRow()){
                  send(',');
                  send(toJSON(row));
              }
          }
          return ']';
      }

JSON

  JSON object.

isArray(obj)

  A helper function to check if the provided value is an Array.

  Arguments:

    - obj – Any JavaScript value

  Returns:

    `true` if obj is Array-typed, `false` otherwise

  Return type:

    boolean

log(message)

  Log a message to the CouchDB log (at the INFO level).

  Arguments:

    - message – Message to be logged

      function(doc){
          log('Procesing doc ' + doc['_id']);
          emit(doc['_id'], null);
      }

  After the map function has run, the following line can be found in CouchDB logs (e.g. at /var/log/couchdb/couch.log):

      [Sat, 03 Nov 2012 17:38:02 GMT] [info] [<0.7543.0>] OS Process #Port<0.3289> Log :: Processing doc 8d300b86622d67953d102165dbe99467

provides(key, func)

  Registers callable handler for specified MIME key.

  Arguments:

    - key – MIME key previously defined by `registerType()`

    - func – MIME type handler

registerType(key, *mimes)

  Registers list of MIME types by associated key.

  Arguments:

    - key – MIME types

    - mimes – MIME types enumeration

  Predefined mappings (key-array):

  - all: `*/*`

  - text: `text/plain; charset=utf-8`, `txt`

  - html: `text/html; charset=utf-8`

  - xhtml: `application/xhtml+xml`, `xhtml`

  - xml: `application/xml`, `text/xml`, `application/x-xml`

  - js: `text/javascript`, `application/javascript`, `application/x-javascript`

  - css: `text/css`

  - ics: `text/calendar`

  - csv: `text/csv`

  - rss: `application/rss+xml`

  - atom: `application/atom+xml`

  - yaml: `application/x-yaml`, `text/yaml`

  - multipart_form: `multipart/form-data`

  - url_encoded_form: `application/x-www-form-urlencoded`

  - json: `application/json`, `text/x-json`

require(path)

  Loads CommonJS module by a specified path. The path should not start with a slash.

  Arguments:

    - path – A CommonJS module path started from design document root

  Returns:

    Exported statements

send(chunk)

  Sends a single string chunk in response.

  Arguments:

    - chunk – Text chunk

      function(head, req){
          send('Hello,');
          send(' ');
          send('Couch');
          return ;
      }

start(init_resp)

  Initiates chunked response. As an option, a custom response object may be sent at this point. For list-functions only!

  Note

  list functions may set the HTTP response code and headers by calling this function. This function must be called before `send()`, `getRow()` or a return statement; otherwise, the query server will implicitly call this function with the empty object (`{}`).

      function(head, req){
          start({
              "code": 302,
              "headers": {
                  "Location": "http://couchdb.apache.org"
              }
          });
          return "Relax!";
      }

sum(arr)

  Sum arr’s items.

  Arguments:

    - arr – Array of numbers

  Return type:

    number

toJSON(obj)

  Encodes obj to JSON string. This is an alias for the `JSON.stringify` method.

  Arguments:

    - obj – JSON-encodable object

  Returns:

    JSON string

## 3.2.2. CommonJS Modules

Support for CommonJS Modules (introduced in CouchDB 0.11.0) allows you to create modular design functions without the need for duplication of functionality.

Here’s a CommonJS module that checks user permissions:

    function user_context(userctx, secobj) {
        var is_admin = function() {
            return userctx.indexOf('_admin') != -1;
        }
        return {'is_admin': is_admin}
    }

    exports['user'] = user_context

Each module has access to additional global variables:

- module (object): Contains information about the stored module

  - id (string): The module id; a JSON path in ddoc context

  - current (code): Compiled module code object

  - parent (object): Parent frame

  - exports (object): Export statements

- exports (object): Shortcut to the `module.exports` object

The CommonJS module can be added to a design document, like so:

    {
        "views": {
            "lib": {
                "security": "function user_context(userctx, secobj) { ... }"
            }
        },
        "validate_doc_update": "function(newdoc, olddoc, userctx, secobj) {
            user = require('views/lib/security').user_context(userctx, secobj);
            return user.is_admin();
        }"
        "_id": "_design/test"
    }

Modules paths are relative to the design document’s `views` object, but modules can only be loaded from the object referenced via `lib`. The `lib` structure can still be used for view functions as well, by simply storing view functions at e.g. `views.lib.map`, `views.lib.reduce`, etc.