spotfiresoftware / spotfire-mods

Spotfire® Mods
https://spotfiresoftware.github.io/spotfire-mods/
Other
54 stars 41 forks source link

Action Mods ReplaceValuesTransformation does not allow replacement of `(Empty)` values #149

Closed nikomaresco-csg closed 2 months ago

nikomaresco-csg commented 2 months ago

in Spotfire Analyst, i'm able to create a new Replace Values transformation, leave the "Previous value" field blank, and enter any data type into the "Replace value with" field:

image

this allows me to replace (Empty) (or as it's shown here, (Empty value)) with a new value.

reproducing this with the Action Mods API is not possible. the following code fails with the error below:

const t = new ReplaceValuesTransformation(columnToReplace, null, 0);
Error: The argument newValue must have the same data type as the column, in this case String
Parameter name: newValue
    at createReplaceValuesTransform (C:\Users\...\.js:72:15) ->     const t = new ReplaceValuesTransformation(columnSignature, null, newValue);

this is repeatable with the following values: null, undefined, (Empty)

as a workaround, i was able to use the SN() function in a ReplaceColumnTransformation:

const t = new ReplaceColumnTransformation(columnToReplace, resultColumnName, "Real(SN([Value], '0'))";

if this workaround is the desired path, it should be mentioned in the documentation for ReplaceValuesTransformation. otherwise, there should be a way to indicate (Empty) in either the originalValue or newValue parameter.

https://spotfiresoftware.github.io/spotfire-mods/api-docs/action-mods/classes/Spotfire.Dxp.Data.Transformations.ReplaceColumnTransformation.html

nikomaresco-csg commented 2 months ago

i figured out what was going on. tl;dr, i was mistaken and this report is innacurate and should be closed.

in my mod, i was trying to create a sequence of transformations consisting of an Unpivot followed by a Replace Values. i did not realize that it is required to specify UnpivotTransformation.ResultType; without setting this field, it defaults to a string.

a snippet from my corrected code in case:

    const step2_unpivot = new UnpivotTransformation();
    step2_unpivot.CategoryName = "Category";
    step2_unpivot.CategoryType = DataType.String;
    step2_unpivot.ResultName = "Value";
// this is the line that was missing:
    step2_unpivot.ResultType = DataType.Real;
    step2_unpivot.IdentityColumns = TypedArray.create(
        DataColumnSignature,
        identityColumnSignatures
    );
    step2_unpivot.ValueColumns = TypedArray.create(
        DataColumnSignature,
        newPivotColumns.map(col => new DataColumnSignature(col))
    );

    dfb.AddTransformation(step2_unpivot);
    flow = dfb.Build();
    reader = dfb.Execute(DataSourcePromptMode.None);

    const valueColumn = OutParam.create(DataRowReaderColumn);
    reader.Columns.TryGetColumn("Value", valueColumn.out)!;
    const valueColumnSignature = new DataColumnSignature(valueColumn);

    const typedValue = OutParam.create(System.Object);
    if (!valueColumn.DataType.Formatter.TryParse("0.0", typedValue.out))
        throw new Error("Cannot parse 0.0 to the correct type for the Value column.");

    const step3_replaceValues = new ReplaceValuesTransformation(valueColumnSignature, null, typedValue);
    dfb.AddTransformation(step3_replaceValues);