now-context: Opensource Project

Happy New Year! Lately I’ve been working on ways to simplify and enhance the way in which we develop applications. I watched this video: The Reusable JavaScript Revolution¬†which¬†really got my brain working and trying to come up with a solution for Red Pill Now. One of the pieces of the application part of that project is a context element (now-context) that provides a few different features:

  • Performs and records all AJAX requests
  • Provides a basic PubSub system
  • Provides a basic Request/Response service
  • Provides a global variable to interact with the context

The entire idea here is to provide a communication channel similar to that found in Backbone/Backbone Marionette for application specific communication. Sure, we could use native events, however you would have to build a lot of scaffolding around that.


This feature ends up supplying a solution (not sure yet if it’s a good solution) to the problem that Polymer has no PubSub system. Everything is done with native events and data-binding. While this is workable it can sometimes be a pain and prone to having memory leaks because you didn’t remove an event listener(s). We want to alleviate this pain and have an application specific communication channel.

So the basic idea here is, you subscribe to an event and provide it a callback function. Then anytime that event occurs your callback will be executed. For example, you have a list of ToDos and anytime a ToDo is created or deleted you want to increment a counter in some other element. You could do this via data-binding, but maybe the counter and ToDo list are siblings, which means now you have to implement a parent element to control all of that data. OR, you could just publish an event when a ToDo is created/deleted and subscribe to that event. That gets rid of having an empty element whose sole purpose is to shuffle data back and forth. The code for this would look something like this:

Setup the listener, we use a setTimeout mainly to allow time for NowContext to be initialized:

connectedCallback() {
  // Wait for now-context to be initialized
  setTimeout(() => {
    NowContext.listenEvt('nowContextItemUpdated', this.onContextItemUpdated);
  }, 1000);

onContextItemUpdated(data) {
  // Do Stuff...

Setup the trigger:

let data = {
  foo: 'bar',
  bar: 'baz'
NowContext.triggerEvt('nowContextItemUpdated', data)

Anytime the ‘nowContextItemUpdated’ event is fired, it will run all of it’s subscribed listeners. This can be very handy if something is changing a lot.

ReqRes Service

This feature provides a means to request something and then provide a response to that request. The request could be for anything: something from the server, something from an element or just some property somewhere. This is very similar to the PubSub event listener and trigger, however the publisher of whatever you might be requesting subscribes to the event and that listener MUST return a Promise. Then whichever element is requesting that information triggers the event.

// The element which has access the data var below would be the element that subscribed to the event
let data = {foo: 'bar', bar: 'baz'};
NowContext.listenEvt('someEvt', () => {
    return new Promise((resolve, reject) => {
}, null);

We pass along the event name and a handler/callback for that event. The callback MUST return a Promise.

And then to request that data:

  .then((data) => {
    console.log('data=', data);
    // Do Stuff...

Making a request from the server follows a similar pattern:

  ajax: {
    method: 'GET',
    url: ''
  idKey: 'id'
  .then((ajaxRequest) => {
    console.log('ajaxRequest=', ajaxRequest);
    // Do Stuff with the response....

What’s happening behind the scenes above is:

  • We call the reqres function which returns a Promise (line 1)
    • That function is passed an object that has an ajax property and that object needs to contain everything needed to make an AJAX request. (lines 1-7)
  • The AJAX information is passed to a call to the web worker to do the request
  • The web worker makes the request and then passes the response back to now-context
  • now-context updates it’s context property, fires the ‘nowContextItemUpdated’ or ‘nowContextItemAdded’ event and resolves the Promise passing the AjaxRequest object back to the caller (line 8)
  • The .then part of the Promise then runs and can utilize the ajaxRequest (lines 9, 10)

We can even combine the ReqRes event and Server request. Here is the subscriber/listener for the event:

let data = {foo: 'bar', bar: 'baz'};
NowContext.listenEvt('someEvt', () => {
  return new Promise((resolve, reject) => {
    NowContext.reqres({ ajax: { url: '', method: 'GET' }, idKey: 'id' })
      .then((ajaxReq) => {

And then the publisher of the event will actually trigger the event:

  .then((ajaxReq) => {
    // Do Stuff...

I realize some of the names of things here are quite confusing, I am working on making this a little more friendly, so if you use this project, don’t get too comfy with the function names.


The context is a place to store things (again, I know the naming here sucks). Currently, anytime the reqres function is called and a response provided, we add the response to the context. We have also been discussing the ability to add random items to the context. If a request is made for an item already in the context, we update that item. There are 2 events here that get fired:

  • nowContextItemUpdated – Fired when a context item is updated
  • nowContextItemAdded – Fired when a context item is added

So it wouldn’t be much of a context if you couldn’t get things from it. Since the context is nothing but an Object we can just access it directly:


In theory you could add stuff to the context here, I don’t prevent it. However, in the future I do want to limit that and provide an authorized process to add/remove things to the context.

You can find the now-context element on GitHub.

I hope you find this element useful or at least is a source of ideas to create your own solution. Until next time… Happy Coding!

Share This:

Leave a Reply

Your email address will not be published. Required fields are marked *