igniteui-angular
igniteui-angular copied to clipboard
Migration support for dangling objects, adding derived properties
Is your feature request related to a problem? Please describe.
When writing migrations, it is not currently possible to add a property dependant on another property. Example:
import { FilteringExpressionsTree } from 'igniteui-angular';
const tree = new FilteringExpressionsTree(0, 'test');
tree.filteringOperands.push({
fieldName: 'ID',
condition: IgxStringFilteringOperand.instance().condition('contains'),
searchVal: 'a',
ignoreCase: true
});
Should become:
import { FilteringExpressionsTree } from 'igniteui-angular';
const tree = new FilteringExpressionsTree(0, 'test');
// Either extract the object to a var and set the conditionName property to condition.name e.g.:
let operand = {
fieldName: 'ID',
condition: IgxStringFilteringOperand.instance().condition('contains'),
searchVal: 'a',
ignoreCase: true
};
operand.conditionName = operand.condition.name;
tree.filteringOperands.push(operand);
// Or grab the value of the condition being pushed, and append a line with the value and name appended, a la $1.name
// e.g.:
tree.filteringOperands.push({
fieldName: 'ID',
condition: IgxStringFilteringOperand.instance().condition('contains'),
conditionName: IgxStringFilteringOperand.instance().condition('contains').name,
searchVal: 'a',
ignoreCase: true
});
// Note: tree.filteringOperands = [{ ... }] should also be considered.
Describe the solution you'd like
See the example code above.
Describe alternatives you've considered
Regex matching was considered, but there is a possibility of mismatching on unrelated objects, which would not be ideal.
Additional context
It is a dangling object so no type information is inferred by the LanguageService; The filteringOperands property is the best bet of correctly identifying migration cases.
@Otixa Been considering a value transform callback of sorts (we have one in other migration types already) for another feature PR, which could possibly overlap with this.
The most direct approach with our current matching setup would be to target the offending property directly, in this case IFilteringExpression.condition, that way we can resolve the type on matches and it should work in both those case:
tree.filteringOperands.push({
condition: IgxStringFilteringOperand.instance().condition('contains'),
/* ... */
});
// OR
tree.filteringOperands = [{ condition: /* ... */ }]
In both of those cases the object type should be inferred to the filtering expression type.
The let operand = {} example with just schema alone would be quite a bit more cumbersome to match, though it would also work fine if typed let operand: IFilteringExpression.
Actually, this could also just be expanded into a direct replace even closer to what we have right now. Would something like this cover the request?
{
"$schema": "../../common/schema/members-changes.schema.json",
"changes": [
{
"member": "condition",
"replaceWith": "conditionName",
"valueTransform": "operandInstanceToName"
"definedIn": [ "IFilteringExpression" ]
}
]
}
That's assuming the value transform is given the option to skip/ignore the replacement altogether if the value can't be converted, still very TBD. I'm considering making the replaceWith optional as well if value transform is provided, so that can be used just to modify the value of some property without renaming it, though in this case I think we actually could.
@damyanpetev I suppose that would do the trick, yes. Except the original property should be kept and not replaced.
How would the valueTransform be used in this scenario? Would it pass all the matching symbols/expressions/blackmagic into the callback?
There has been no recent activity and this issue has been marked inactive.