I have a new app that I am making as a pet project that one of my components is behaving wrong.
I have a complex object that stores the information for D&D monsters. The component is for a option quantity changer with plus and minus buttons the increment and decrement the quantities.
When I use it for a tier 1 child (ie. monster.strength) it works correctly and will increment up to the maximum quantity, and down to the base value (but not below base) When I use it for a tier 2 child (ie. monster.speed.base) it will increment correctly, but it actually changes the basemonster value as well as the selectedmonster which prevents the decrement from working.
Here's the code showing how the objects are added to the document.
<option-quantity *ngIf="mod.location === 'base'"
[max]="90"
[step]="5"
[costval]="mod.cost"
[baseval]="baseMonster[mod.type][mod.location]"
[(totalcost)]="selectedMonster.cost"
[(optval)]="selectedMonster[mod.type][mod.location]">
</option-quantity>
And here is the components TS file
import { Component, Input, Output } from '@angular/core';
import { EventEmitter } from '@angular/core';
@Component({
selector: 'option-quantity',
templateUrl: './option-quantity.component.html',
styleUrls: ['./option-quantity.component.css']
})
export class OptionQuantityComponent {
@Output('optvalChange') emitter1: EventEmitter<number> = new EventEmitter<number>();
@Output('totalcostChange') emitter2: EventEmitter<number> = new EventEmitter<number>();
@Input('baseval') set setBaseVal(value) {
this.base = value;
}
@Input('optval') set setOptValue(value) {
this.count = value;
}
@Input('costval') set setCostValue(value) {
this.cost = value;
}
@Input('totalcost') set setTotalCostValue(value) {
this.totalcost = value;
}
@Input('step') set setStepValue(value) {
this.step = value;
}
@Input('max') set setMaxValue(value) {
this.max = value;
}
step = 1;
max = 10;
base = 0;
count = 0;
cost = 0;
totalcost = 0;
increment() {
if (this.count < this.max) {
this.count += this.step;
this.totalcost += this.cost * this.step;
this.emitter1.emit(this.count);
this.emitter2.emit(this.totalcost);
}
}
decrement() {
if (this.count > this.base) {
this.count -= this.step;
this.totalcost -= this.cost * this.step;
this.emitter1.emit(this.count);
this.emitter2.emit(this.totalcost);
}
}
onChange() {
this.emitter2.emit(this.totalcost);
this.emitter1.emit(this.count);
}
}
I have verified the problem lies with the tier 2 child, since i tried moving the stats into a stats child, and the speed to the root. Which made the stats stop working and the speed work fine. I COULD just move the speed to the root of the object, but I'd rather not.
The component where the values are used is the create-undead component the baseMonster is created by this function:
setBase() {
this.baseMonster = Object.assign({}, this.selectedMonster);
this.currentSize = this.baseMonster.size;
this.previousSize = this.baseMonster.size;
}
The entire project can be viewed in my GitHub repo
Updates: I've tried using Object.spread instead of assign, but that didn't make any difference. If I use Object.freeze and do a deep freeze on the "baseMonster" object, that object will not change, but then the "selectedMonster" stops having its tier 2 child values update.
Any help would be greatly appreciated.