Seeking a solution to run specific code around the put()
and add()
functions for Dojo stores, I encountered an issue with JSON REST stores where add()
simply calls put()
:
add: function(object, options){
options = options || {};
options.overwrite = false;
return this.put(object, options);
},
Using aspect.around()
with add()
causes my code to run twice if applied to stores created with a store that treats add()
as a shortcut to put()
.
I understand that this is a common practice among most stores, but I want my solution to work seamlessly with any store, regardless of method nesting.
Dojo's Observable.js
faces a similar challenge and handles it in the following manner:
function whenFinished(method, action){
var original = store[method];
if(original){
store[method] = function(value){
if(inMethod){
return original.apply(this, arguments);
}
inMethod = true;
try{
var results = original.apply(this, arguments);
Deferred.when(results, function(results){
action((typeof results == "object" && results) || value);
});
return results;
}finally{
inMethod = false;
}
};
}
}
whenFinished("put", function(object){
store.notify(object, store.getIdentity(object));
});
whenFinished("add", function(object){
store.notify(object);
});
whenFinished("remove", function(id){
store.notify(undefined, id);
});
The question remains: Is there a concise way to modify my current code to check if it's already within a method, thus preventing duplicate execution?
I attempted to streamline my code but ended up with a clumsy, makeshift solution. It seems like I'm overlooking something simpler...
This is my current code snippet:
topic.subscribe( 'hotplate/hotDojoStores/newStore', function( storeName, store ){
aspect.around( store, 'put', function( put ){
return function( object, options ){
return when( put.call( store, object, options ) ).then( function( r ) {
var eventName;
var identity = store.idProperty;
eventName = object[ identity ] ? 'storeRecordUpdate' : 'storeRecordCreate';
topic.publish( eventName, null, { type: eventName, storeName: storeName, objectId: r[ identity ], object: object }, false );
} );
}
});
aspect.around( store, 'add', function( add ){
return function( object, options ){
return when( add.call( store, object, options ) ).then( function( r ) {
var identity = store.idProperty;
topic.publish('storeRecordCreate', null, { storeName: storeName, storeTarget: storeTarget, objectId: r[identity], object: object }, false } );
});
}
});
});