'use strict'; var EventEmitter = require('events').EventEmitter, globalChannel = new EventEmitter(), Rx = require('rx'), nutrients = require('./food-objects/nutrients'), nutrients, defaultHandlers = { onError: function (err) { console.log('Error: ' + err); }, onComplete: function () { console.log('Completed'); } }, globalChannelDestroyEvent = Rx.Observable.fromEvent( globalChannel, 'destroy').take(1), // declaration //----------------------------------------- frenchFryNutrition = Object.create( nutrients ); // using delegation pattern // lazy instantiation //----------------------------------------- frenchFryNutrition.initNutrition({ state: { salt: 100, sugar: 95, calories: 50 }, init: function() { console.log('init was called on this stateContainer'); } }); // events //----------------------------------------- // create observables Rx.Observable.fromEvent( globalChannel, 'nutrientRequest', function( eventArgs ) { return frenchFryNutrition.getState()[ eventArgs[0] ]; }). takeUntil(globalChannelDestroyEvent). subscribe( function( response ) { globalChannel.emit( 'nutrientResponse', response ); }, defaultHandlers.onError, defaultHandlers.onComplete ); Rx.Observable.fromEvent( globalChannel, 'nutrientResponse' ). takeUntil(globalChannelDestroyEvent). subscribe( function( response ) { console.log( response ); }, defaultHandlers.onError, defaultHandlers.onComplete ); //----------------------------------------- // main //----------------------------------------- console.log(frenchFryNutrition.getNutrients()); // { salt: 100, sugar: 95, calories: 50 } // test that we got a value not reference nutrients = frenchFryNutrition.getNutrients(); nutrients.salt = 25; // this does not work because getNutrients() returns a shallow copy not a reference console.log(frenchFryNutrition.getNutrients()); // { salt: 100, sugar: 95, calories: 50 } // test modification of ingredient frenchFryNutrition.setNutrients({ salt: 5 }); console.log(frenchFryNutrition.getNutrients()); // { salt: 5, sugar: 95, calories: 50 } // test events globalChannel.emit('nutrientRequest', 'salt'); // 5 globalChannel.emit('nutrientRequest', 'sugar'); // 95 globalChannel.emit('nutrientRequest', 'calories'); // 50 globalChannel.emit('destroy'); // Completed\nCompleted // output //----------------------------------------- // $ node index.js // init was called on this stateContainer // { salt: 100, sugar: 95, calories: 50 } // { salt: 100, sugar: 95, calories: 50 } // { salt: 5, sugar: 95, calories: 50 } // 5 // 95 // 50 // Completed // Completed