Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save matthewstokeley/71506a9e124d36570e839d904c844a5a to your computer and use it in GitHub Desktop.
Save matthewstokeley/71506a9e124d36570e839d904c844a5a to your computer and use it in GitHub Desktop.
Listening to the life cycle of a mutating object
<block data-src="src" data-alt="hello"></block>
<button onclick="click(event)">
// original data

var data = {
	src: '',
	alt: ''
}

// wonky object mutator

var mutateObjectProperties = (original, update) => {
    
    var walkObject = (object, fn) => {
    	for (var property in object) {
    		fn.call(this, property, object)
    	}
    }

    var doesObjectHaveOwnProperty = (object, property) => object.hasOwnProperty(property)

    // if properties exist in both  the original and the update

    var updateProperties = (property, object) => {
    	if (!doesObjectHaveOwnProperty)
    	    return false

	original[property] = typeof update[property] === 'object'
	    ? updateObjectProperties(original[property], update[property]
	    : update[property]] 
	
    }


    // if there is a property in the update object
    // that is not in the original

    var addProperties = (property, object) => {
    	if (!doesObjectHaveOwnProperty())
    	    return false

    	return !original[property]
	    ? original[property] = update[property]
	    : ''
    }

    // these should be sequenced
    walkObject(original, updateProperties)
    walkObject(update, addProperties)

    return original;
	
}

// click handler

function onclick(event) {
	event.preventDefault();
	
	// create a payload
	var update = {
		_name: 'name',
		src: event.target.dataset.src
	};

	// extend the method with an event emitter
	// - could also chain methods
	// - original data object should be cloned
	// the first argument could be another emitter function
	// that would provide a 'pre-mutate' event. 
	var mutate = __.extendMethod(
		() => event.emit('object-about-to-change', update), 	
		[
		    mutateObjectProperties, 
		    () => event.emit('object-changed', update)
		]
	) 
	
	// mutate data and fire event
	// if this mutate function is used, any time 
	// any object is changed, the event will fire
	mutate(data, update);

}

// now we can watch for mutated objects and objects about to mutate
event.register('object-about-to-change', (payload) => {
})

event.register('object-changed', (payload) => {    
})
@matthewstokeley
Copy link
Author

Button tag isn’t closed.

@matthewstokeley
Copy link
Author

matthewstokeley commented Dec 30, 2018

Also, see vue.js setReactiveProperty for a much better implementation. The Vue developers are integrating custom getter and setter methods that contain messaging functionalities, described by the es6 in depth series as the way to implement reactive features with an object. Apache’s Kafka, which provides partioned topics with the observer pattern, allows the user to implement reactive principles, or at least an event-based approach toward an immutable object’s property assignment. (I haven’t read Kafka’s source).

The vue router uses a queue to sequence routing life-cycle event emissions. This is a well-defined concept - I think I’ve seen this pattern being used recently in implementations of the InteractionObserver api.

Chaining, queues and cascading a literal set of related event emissions are “well-defined implementation techniques” - a queue is probably the most appropriate in this circumstance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment