# JSChannel Documentation

Verifying the correctness of the code on this page...

All the code on this page is correct.

Some code on this page doesn't work.

## Introduction

JSChannel is a small JavaScript abstraction layer on top of HTML5 cross-document messaging. It builds rich messaging semantics out of `window.postMessage()`.

## About The Code Examples

This page uses the doctestjs library by Ian Bicking. The code examples are actually run on your browser to verify their correctness.

All the code examples in this documentation assume communication between a parent page and a child frame. Example code executed in the child frame looks like this:

The examples also assume that a few global functions exist in the parent page:

- `emit()` simply prints out its arguments, like so:

## Page Setup

JSChannel has no dependencies, so there's very little setup involved. You can get started by making a simple HTML page that includes the JSChannel script:

    <script src="jschannel.js"></script>

And a trivial child frame:

    <iframe id="childId" src="child.html"></iframe>

The contents of the child frame don't matter, so long as it includes the JSChannel script (so that it can communicate with its parent).

Note that we're just using a child frame for the sake of example; as a rule, JSChannel can be used anywhere that `window.postMessage()` can.

## Creating a Channel

Let's create a channel in our child frame:

And now we'll build one in our parent page to communicate with it:

Note that the `onReady` callback is called once actual communication has been established between the parent page and child frame. If the child frame hadn't set up its end of the channel, for instance, `onReady` would never get called.

If you pass a bogus first parameter to `Channel.build()`, a friendly exception is thrown.
The `origin` parameter is used for security purposes, just as in `window.postMessage()`, and it can take many different forms:
...except for obvious exceptions.
And the `scope` parameter can include almost any characters to automatically namespace the channel so it doesn't conflict with other channels:
But a channel's scope can't include double colons.

## Remote Methods

Now we'll define a simple function in our child frame:

And call it in our parent frame.

Of course, more than just strings can be returned from a remote call. Assume we have a trivial echo function like this:

It's possible for a remote method to return any native JavaScript types, like numbers:

`null` works, too:

As do booleans:

Remote methods can throw errors, too. Here's one in our child frame:

Calling that produces this:

But objects with keys other than `error` and `message`...

...get smushed into strings by attempting to serialize them to JSON.

But objects that can't be serialized to JSON just get coerced to strings:

You can throw arrays, too:

And strings...

Totally unintentional exceptions get propagated, too:

### Transactions

If your method's implementation is asychronous, you'll have to use the transaction object that's automatically passed as the first argument to a remote method, like so:

The caller doesn't do anything differently, since it's always calling the remote method asynchronously:

You can use a transaction's `error()` method to propagate errors, too.

### Callbacks

Clients can pass functions as parameters to remote methods, and they can be called by the implementer. Here's a trivial example:

Callback parameters can be nested, too, and they arrive in the order in which they were originally called:

### Timeouts

Clients can also be notified if a remote method invocation takes too long to complete by passing a `timeout` parameter to a channel's `call()` method.

For instance, we can try calling a nonexistent method with a timeout:

Of course, the timeout doesn't get triggered if the method call actually completes...

## Notifications

Notifications are similar to method calls, but are "fire-and-forget", lacking any concept of an error or return value. For example:

Learn more about »