Closed bkak closed 10 years ago
Can you do an example? I've not understood so good...
Ya sure,
Here is the AR :
-- ReceiptPaymentAR.js
module.exports = base.extend({
this._account = "",
this._amount = 0
});
I want to explicitly declare AR properties in AR itself. These properties should be filled up while loading AR from EventStore. Right now "this.attributes" is being filled up.
ok, so you want to have separate attributes? And why?
Yes separate attributes is what I mean.
If I have separate attributes it helps me see the structure of my AR and their properties. Semantically also it helps avoid typo errors. Naming mistakes like if one command calls one property as "bank" another command calls it as "bankname" can also be avoided. It will also help other developers working on the same AR. Right now to see the structure of AR we have to see the commands.
So it's more a declarative way to say: "This aggregate uses the following data structure..."
If it's more declarative... why not just do it yourself?
module.exports = base.extend({
datastructure: {
"myProp": {},
"myProp2": {}
},
changeDummy: function(data, callback) {
this.apply(this.toEvent('dummyChanged', data));
this.checkBusinessRules(callback);
}
});
Hey ya..I tried this.
There is a small problem in this. I shall post the sample with the problem tomorrow.
I am using domain-cqs project. Here it goes:
ReceiptPaymentAR.js :
module.exports = base.extend({ customattributes: { amount:0, accountid:"", details:[] } //commands & events });
aggregateBase.js :
set: function(data) {
this.attributes = .extend(this.attributes, this.customattributes);
if (arguments.length === 2) {
this.attributes[arguments[0]] = arguments[1];
} else {
for(var m in data) {
self.attributes[m] = data[m];
}
}
}
This merges the structure and works great for 1st command on an AR instance. However, on the second command on the same AR with the same instance, the datastructure(customattributes) does not get reset. I think it becomes static, so the details collection holds older values in the array("details" attribute). When second command fetches the AR from mongo and fills it up using set method, the older values and newer values get merged because of .extend that I have used in order to fill up my datastructure. This results in doubling of the values in array. I am sure I am missing something.
Is this the correct way to make it more declarative?
Ok, now I'm confused... I thought you just want to see the datastructure to lookup for example the attribute names... so finally documentation... You can just make a comment block on top of the aggregate file. Isn't this enough? Or what is the reason to use this programmatically?
Il giorno 4-dic-2013, alle ore 06:13, "Bhoomi" notifications@github.com<mailto:notifications@github.com> ha scritto:
I am using domain-cqs project. Here it goes:
ReceiptPaymentAR.js :
module.exports = base.extend({ customattributes: { amount:0, accountid:"", details:[] } //commands & events });
aggregateBase.js :
set: function(data) { this.attributes = _.extend(this.attributes, this.customattributes); if (arguments.length === 2) { this.attributes[arguments[0]] = arguments[1]; } else { for(var m in data) { self.attributes[m] = data[m];
} } } This merges the structure and works great for 1st command on an AR instance. However, on the second command on the same AR with the same instance, the datastructure(customattributes) does not get reset. I think it becomes static, so the details collection holds older values in the array("details" attribute). When second command fetches the AR from mongo and fills it up using set method, the older values and newer values get merged because of _.extend that I have used in order to fill up my datastructure. This results in doubling of the values in array. I am sure I am missing something.
Is this the correct way to make it more declarative?
— Reply to this email directly or view it on GitHubhttps://github.com/adrai/node-cqrs-domain/issues/14#issuecomment-29780134.
Oh no no not for documentation purpose.
It also helps in intellisense and readability, and to make the structure finite in terms of AR. I have done one full-fledged implementation of CQRS in C#.NET, that being a typed language there was a definite AR with all the private properties.
Javascript being untyped language this can be very well achieved without declaring the properties explicitly, but making AR properties explicit helps a lot.
Ok, you think about a schema?
I have not implemented something like a schema in the aggregate explictly because of the possible different versions of an aggregate...
Il giorno 4-dic-2013, alle ore 07:45, "Bhoomi" notifications@github.com<mailto:notifications@github.com> ha scritto:
Oh no no not for documentation purpose.
It also helps in intellisense and readability, and to make the structure finite in terms of AR. I have done one full-fledged implementation of CQRS in C#.NET, that being a typed language there was a definite AR with all the private properties.
Javascript being untyped language this can be very well achieved without declaring the properties explicitly, but making AR properties explicit helps a lot.
— Reply to this email directly or view it on GitHubhttps://github.com/adrai/node-cqrs-domain/issues/14#issuecomment-29783256.
Yes the schema.
By possible different versions of the aggregate we can change the schema accordingly. Since I am using CQS this loads the AR instance directly and does not replay the events, so keeping the schema wont be a problem.
Any clues, how this can be achieved?
Hmmmmm...
When should a property be validated? When calling set? What should happen if the validation fails? Throw an error?
Il giorno 4-dic-2013, alle ore 07:57, "Bhoomi" notifications@github.com<mailto:notifications@github.com> ha scritto:
Yes the schema.
By possible different versions of the aggregate we can change the schema accordingly. Since I am using CQS this loads the AR instance directly and does not replay the events, so keeping the schema wont be a problem.
Any clues, how this can be achieved?
— Reply to this email directly or view it on GitHubhttps://github.com/adrai/node-cqrs-domain/issues/14#issuecomment-29783681.
Hmm no mostly I do not intend to do the validations while setting any property. I am assuming command is validated. But for calculation purpose I want to use SOM like (set, testset and doset) properties as follows :
settotalamount : function(){ var sum = 0; .each(this._details, function(d){ sum += d.totalamount(); }); this.testset_totalamount(); this.doset_totalamount(sum); }, testset_totalamount : function(v){ }, doset_totalamount : function(v){ this.attributes._totalamount = v; },
In general I am thinking to have validation of AR state and check its invariant and if invariant fails raise compensation event. Do not intend to raise exception. In some cases I might as well raise exception, till now I have not felt the need of it.
I've not tested, but is this code not working in the aggregate? If you extend the aggregate with this functions and call them when you want?
This code works in aggregate if I do not define my schema. If I extend the schema using _.extend in the aggregateBase as shown above it does not reset my datastructure while filling the data from mongo.
Wait I shall create a sample of the case in my repo and share the link in a while.
Hey I have replicated the case here : https://github.com/bkak/cqrs-sample-master-with-entity
It's your item sample with an entity in it.
It seems the problem is when the property of AR is an entity. I have loaded AR properties and its entities while loading the AR in aggregateBase.js in its .set method. It seems older entities are not being reset.
Check out the set method in aggregateBase.js, I have console logged the unit count. On subsequent edits of item the units collection doubles.
Why are you extending this.atributes? Can't you save your customattributes separately for example in this.customattributes and create an own set and get function for example setCustom and getCustom? What do you want to do with this customAttributes?
PS. Perhaps these lines: https://github.com/bkak/cqrs-sample-master-with-entity/blob/master/host/public/js/app.js#L153 aren't so correct: an object with 2 properties with the same name
Yes I can create separate this.customattributes and not extend this.attributes. This code adds default attributes like these : this.attributes = { id: id, revision: 0, destroyed: false };
So I thought to extend base attributes. But I could not understand why the entities object is not being reset even when Aggregate's object is created.
Ya there is a mistake in app.js.
Hi,
Is there a way to specify explicit attributes in Aggregate.
In AggregateBase.js file there is Aggregate object literal which has attributes property. This attributes property has 3 more additional properties. Is there a way to extend this Attributes of Aggregate and define my own prop bags instead of always relying on the command and/or eventstore to generate my AR?