Skip to content

Commit

Permalink
Merge pull request #927 from concord-consortium/186201130-formula-att…
Browse files Browse the repository at this point in the history
…r-delete

Fix a bug that was causing an error when attr with formula was deleted
  • Loading branch information
pjanik authored Oct 10, 2023
2 parents 1e714d4 + 016773d commit 548b182
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions v3/src/models/data/formula-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { comparer, makeObservable, observable, reaction } from "mobx"
import { isAlive } from "@concord-consortium/mobx-state-tree"
import { EvalFunction } from "mathjs"
import { FormulaMathJsScope } from "./formula-mathjs-scope"
import { CaseGroup, ICase, IGroupedCase, symParent } from "./data-set-types"
Expand Down Expand Up @@ -245,6 +246,7 @@ export class FormulaManager {
})
return result
}, () => {
this.unregisterDeletedFormulas()
// Register formulas. For simplicity, we unregister all formulas and register them again when canonical form is
// updated. Note that even empty formulas are registered, so the metadata is always available when cycle detection
// is executed.
Expand All @@ -270,7 +272,28 @@ export class FormulaManager {
this.recalculateFormula(formulaId)
}
})
}, { equals: comparer.structural, fireImmediately: true })
}, {
equals: comparer.structural,
fireImmediately: true,
name: "FormulaManager.registerAllFormulas.reaction"
})
}

unregisterDeletedFormulas() {
this.formulaMetadata.forEach((metadata, formulaId) => {
const { dataSetId, attributeId } = this.getFormulaMetadata(formulaId)
const dataSet = this.dataSets.get(dataSetId)
if (!dataSet?.attrFromID(attributeId)) {
this.unregisterFormula(formulaId)
return
}
// In 99% of cases, the two `if` statements above will be sufficient to detect deleted formulas. However, this
// could serve as the ultimate check in case a formula instance was deleted in a different manner.
if (!isAlive(metadata.formula)) {
console.warn("FormulaManager.unregisterDeletedFormulas unregistering a defunct formula that was not detected by the usual means.")

Check warning on line 293 in v3/src/models/data/formula-manager.ts

View workflow job for this annotation

GitHub Actions / S3 Deploy

This line has a length of 138. Maximum allowed is 120
this.unregisterFormula(formulaId)
}
})
}

recalculateAllFormulas() {
Expand Down Expand Up @@ -393,7 +416,10 @@ export class FormulaManager {
// we need to recalculate all formulas.
const disposeAttrCollectionReaction = reaction(
() => Object.fromEntries(dataSet.collections.map(c => [ c.id, c.attributes.map(a => a?.id) ])),
() => this.recalculateAllFormulas(),
() => {
this.unregisterDeletedFormulas()
this.recalculateAllFormulas()
},
{
equals: comparer.structural,
name: "FormulaManager.observeDatasetChanges.reaction [collections]"
Expand All @@ -403,7 +429,10 @@ export class FormulaManager {
// and observe only dependant attributes, but it doesn't seem necessary for now.
const disposeAttrNameReaction = reaction(
() => dataSet.attrNameMap,
() => this.updateDisplayFormulas(),
() => {
this.unregisterDeletedFormulas()
this.updateDisplayFormulas()
},
{
equals: comparer.structural,
name: "FormulaManager.observeDatasetChanges.reaction [attrNameMap]"
Expand Down Expand Up @@ -468,7 +497,9 @@ export class FormulaManager {
break
}

this.recalculateFormula(formulaId, casesToRecalculate)
if (casesToRecalculate.length > 0) {
this.recalculateFormula(formulaId, casesToRecalculate)
}
})

return disposeDatasetObserver
Expand Down

0 comments on commit 548b182

Please sign in to comment.