Dealing with int?, select and dirty indicator

The server provides me an object with a property called caseFK. On the server side, the property is defined as a nullable int – int?.

I have a view that provides a way to edit the object. The caseFK is tied to a <select> element like so:

<select value.bind="editObject.caseFK">
   <option value="">-- Please select a Case --</option>
   <option repeat.for="case of cases" model.bind="case.casePK">${case.Name}</option>
</select>

This much works. However, I also have a dirty indicator that compares the value of the original object against the value of the edited object.

@computedFrom('editObject.caseFK')
get isDirty() : boolean {
    return editObject.caseFK != origObject.caseFK;
}

Because select uses string values, my original value of null becomes '' so the dirty indicator doesn’t always work correctly (e.g. original is null, user selects a value and then de-selects the value using the first option).

I tried using a valueconverter to keep the original type

export class NullableNumberValueConverter {
    toView(value : number){
         return value === null ? '' : value.toString();
    }

    fromView(value: string){
        return !value.length || value == "null" ? null : parseInt(value,10);
    }
}
<select value.bind="editObject.caseFK | nullableNumber"> ... </select>

The problem is that once I introduce the valueconverter, the isDirty indicator stops firing when changes are made to caseFK – I’m not exactly sure why.

My final work-around was to simply change my comparison in isDirty to
origObject.caseFK != (editObject.caseFK.length ? editObject.caseFK : null)

Is there a better way of handling this? Why doesn’t the isDirty() getter get fired when using the value converter?

1 Like

maybe just alter your isDirty function to take null and empty string into account?
I wrote one example here, but you can change it based on our custom logic.

@computedFrom('editObject.caseFK')
get isDirty() : boolean {
    const originEmpty = !origObject.caseFK; //takes care of '' || null || undefined || 0
    const editEmpty = !editObject.caseFK;  //takes care of  '' || null || undefined || 0
    return (originEmpty !== editEmpty ) || (editObject.caseFK !== origObject.caseFK);
}

tidy this a little bit

@computedFrom('editObject.caseFK')
get isDirty() : boolean {
    return (!origObject.caseFK !== !editObject.caseFK ) || (editObject.caseFK !== origObject.caseFK);
}
1 Like