# Namespacing

FootworkJS enables you to organize your code into `namespaces`. Namespaces boil down to a simple `string` identifier which is used to segment off one area from another.

By keeping your modules separate and using a `namespace` to communicate and share state you are more easily able to keep your application loosely coupled.

## Publish / Subscribe

Pub/Sub is a messaging pattern used to aide in decoupling by allowing communication between separate areas of your application without the need of direct references.

With Footwork-based code pub/sub is even more necessary because any declarative viewModel, dataModel, and router instances (along with components) you create will not give you direct references to them. Why? Because you don't explicitly instantiate them.

So in order for you to tell these modules to do things (outside of binding your UI to them) you will need to pass them messages. Footwork facilitates this via its `namespace` feature.

Note

Each `namespace` instance using the same string identifier communicates on the same message bus.

This means that if you create a `namespace` in two places using the same string identifier they will receive the same messages.

### Subscribing to Messages

To receive a message you must first subscribe to its topic, in Footwork this is done by calling `subscribe` on a `namespace` instance and providing it the topic as well as a handler callback.

For example:

    // first create the namespace instance we need to setup our subscription handler on
    var blahNamespace = fw.namespace('blah');

    // create the subscription passing it the topic and callback handler
    var subscription = blahNamespace.subscribe('something-happened', function (thisThingHappened) {
      console.log(thisThingHappened);
    });

In the example above you can see a `namespace` of blah being instantiated and a subscription handler for the something-happened `topic`. The handler defined simply logs any message it receives to the console.

### Publishing a Message

In the preceding example, it showed how to create a `subscription` to the topic something-happened on the `namespace` blah. Lets publish a message to it from some other place in our code:

    /**
     * We need access to the namespace in order to publish a message to it
     * so we create another instance using the same string identifier as before.
     */
    var alsoBlahNamespace = fw.namespace('blah');

    /**
     * Now lets publish a message, all subscriptions listening to the
     * 'something-happened' topic will receive it.
     */
    alsoBlahNamespace.publish('something-happened', 'this thing happened');
    // console logs: 'this thing happened'

The example above shows a new instance of the same blah `namespace` being created, and then a message published on it using the same something-happened `topic` we subscribed to in the earlier example. Because we are sending a message on the same `namespace` and `topic` the handler we setup prior then receives the message and logs it to the console.

## Request / Response

At times you may need to ask a different area of your program for a piece of information (or state). Footwork helps with this by providing an easy way to synchronously request for data via its `namespace`.

### Listening for Requests

To listen for a request you setup a `requestHandler` on a `namespace` for a specific `topic`. This is shown here:

    var blahNamespace = fw.namespace('blah');

    var requestHandler = blahNamespace.requestHandler('what-happened', function () {
      return 'this thing happened';
    });

You can also optionally receive a parameter from the requester:

    var requestHandler = blahNamespace.requestHandler('what-happened', function (param) {
      return 'this thing happened with ' + param;
    });
    var response = blahNamespace.request('what-happened', 'that');
    // response === 'this thing happened with that'

### Requesting data

After creating the request handler, issuing a request is as simple as `request`'ing it:

    var alsoBlahNamespace = fw.namespace('blah');

    var thingThatHappened = alsoBlahNamespace.request('what-happened');
    // thingThatHappened === 'this thing happened'

Using a `namespace` instance with the same blah string identifier as before we request the data. The previously setup handler responds to it and returns our requested data.

### Handling Multiple Responses

You may be asking, what happens if I setup multiple handlers for the same request `topic` on a `namespace`? Well, that depends...

- Receiving only the first response

By default, only the first response is returned.

    var blahNamespace = fw.namespace('blah');

    var requestHandler = blahNamespace.requestHandler('what-happened', function () {
      return 'this thing happened';
    });
    var anotherRequestHandler = blahNamespace.requestHandler('what-happened', function () {
      return 'this other thing happened';
    });

    var thingThatHappened = blahNamespace.request('what-happened');
    console.log(thingThatHappened);
    // console logs: 'this thing happened'

- Receiving all responses

You can optionally pass `true` as the third parameter to `request`, telling Footwork to return all of the responses it receives:

    var thingsThatHappened = blahNamespace.request('what-happened', null, true);

    console.log(thingsThatHappened);
    // console logs: ['this thing happened', 'this other thing happened']

## Sharing State

Pub/Sub and request/receive are great, but what if you just want to share/sync some data across different areas of your code? Footwork provides an easy way to do that via its broadcastable / receivable functionality:

### Broadcast / Receive

A broadcastable and receivable allow you to (in a loosely coupled manner) share data and state between two different areas of your application, keeping them in sync as they are altered.

    // share this value as 'broadcastable' on the 'someNamespace' namespace
    var broadcastable = fw.observable().broadcast('broadcastable', 'someNamespace');

    // receive/sync the value 'broadcastable' from the 'someNamespace' namespace
    var receivable = fw.observable().receive('broadcastable', 'someNamespace');
    // receivable() === undefined

    broadcastable('someValue');
    // receivable() === 'someValue'

For more information see broadcastables / receivables.

## Lifecycle

Any subscriptions or request handlers setup on a `namespace` will hang around in memory until disposed of.

As you may have seen above, a `subscription` is returned each time you setup a request handler or `subscription`. You can explicitely dispose of a single subscription using its `dispose` method:

    var subscription = blahNamespace.subscribe('something-happened', function (thisThingHappened) {
      console.log(thisThingHappened);
    });

    blahNamespace.publish('something-happened', 'this thing happened');
    // console logs: 'this thing happened'

    // dispose of the subscription handler setup above
    subscription.dispose();

    blahNamespace.publish('something-happened', 'this thing happened again');
    // console does not log anything

Another way to dispose of handlers is to dispose of the `namespace` they were created on. Each `namespace` saves a record of each subscriptionn or handler that is setup...so once the `namespace` is disposed it then disposes all of its subscriptions/handlers as well.

    blahNamespace.subscribe('something-happened', function (thisThingHappened) {
      console.log(thisThingHappened);
    });

    blahNamespace.publish('something-happened', 'this thing happened');
    // console logs: 'this thing happened'

    // dispose of the namespace which then disposes its subscription handler setup above
    blahNamespace.dispose();

    blahNamespace.publish('something-happened', 'this thing happened again');
    // console does not log anything

Note

If you are using a `namespace` that is attached to a viewModel, dataModel, or router then it will also be disposed of when the instance it is attached to is disposed of (and of course, its handlers/subscriptions).

## Tools

### Get the string identifier for a namespace

To get the string identifier of an instantiated `namespace` you call the `getName` method:

    var blahNamespace = fw.namespace('blah');

    console.log(blahNamespace.getName());
    // console logs: 'blah'