1

I have an aura component with an input field of type number:

<aura:attribute access="private" name="objs" type="List" />

    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
            <tbody>
                    <aura:iteration items="{!v.objs}" var="objs" indexVar="index">
                        <tr>
                            <td>
                                <div class="slds-truncate wrap" style="font-size: x-small;">
                                    <lightning:input type="number" name="TargetFieldValueField" label="." variant="label-hidden" step="0.0001"
                                                                             value="{!objs.obj.TargetFieldValue__c}" onchange="{!c.onChange}" min="0.0001"/>
                                </div>
                             </td>
                        </tr>
                    <aura:iteration>
            </tbody>
    </table>

The objs List attribute will be filled with records via an apex action in .js controller/helper. The TargetFieldValue__c Field on the object is of type currency (length: 16/2).

Fast forward: In the .js controller I will call another apex action:

 insertFieldValue: function(cmp) {
    cmp.get("v.objs").filter((objw) => {
            return objw.isSelected;
        }).forEach((objw) => {
            objw.obj.sobjectType = 'customObjectForTargetField__c';
            objs.push(objw);
        });
    let action = cmp.get('c.persistValue');
    action.setParams({
        'obj': objs
    });
    action.setCallback(this, $A.getCallback(function (response) {
        let state = response.getState();
        if (cmp.isValid() && state === "SUCCESS") {
            //do other stuff
            self.fireSuccessToast(cmp, "Record was created");
        } else {
            var errors = response.getError();
            self.fireHandleCallBackError(cmp, errors);
        }
    }));
    $A.enqueueAction(action);
}

which will then persist new data which was entered back into that object:

    public static Id persistValue(List<TargetFieldWrapper> objs) {
       List<customObjectForTargetField__c> objsToInsert = new List<customObjectForTargetField__c>();
            for(TargetFieldWrapper objw : objs) {
                    objsToInsert.add(objw.obj);
            }
       insert objsToInsert;
    }

Now, every browser locale/language settings aside, the value which will be passed from javaScript to Apex - if it has decimals - is always a number using a format like 1.8 (dot as a decimal delimiter). However the receiving apex class will handle the number depending on the user's (who calls the apex) locale settings in the org. This might be e.g. some European using comma as a delimiter. Therefore it will receive a value like 1.8, but ignores the dot of course and converts it into 18. In case the locale setting for the apex class calling user will be set to e.g. northern america, it will very well handle the 1.8 as an actual 1.8 in the persist DML method. Is there a way to handle this behavior in a way that it doesn't matter which SFDC locale settings the respective user has in the org?

7
  • 1
    Is JS passing Apex a string representation of the number, or treating it in JSON like a number? If it looks like {"myNumber":"1.8"} then yeah you're gonna have a problem. But if it looks like {"myNumber": 1.8} then you're good because dot is the correct way of writing a number in JSON. Maybe what you need to do is force the value to a number in JS before you call Apex. This could be a function of lightning:input treating numbers like strings.
    – Charles T
    Commented Nov 28, 2019 at 1:40
  • Thanks for the quick response. Yes, it is actually stored as a String it looks like: e.g. {[...],"TargetFieldValue__c":"1.8",[...]}.
    – Cmd_Keen
    Commented Nov 28, 2019 at 7:44
  • Interessting is, that I have another input field in my iteration "Quantity" which looks exactly the same: <lightning:input type="number" name="quantityField" label="." variant="label-hidden" step="1" value="{!objs.obj.Quantity__c}" onchange="{!c.onChange}" min="1"/>. Difference in component is only the step attribute.
    – Cmd_Keen
    Commented Nov 28, 2019 at 11:34
  • Since in javascript the obj which is pushed to objs and which is passed to the component is set to the objecttype of this custom object objw.obj.sobjectType = 'customObjectForTargetField__c'; it is important to mention, that this quantity field is of data type 'number'. Is it possible that in such a case data types of currency are treaded as Strings in component attribute objects and data type number as an actual number ("1.8" vs 1.8)?
    – Cmd_Keen
    Commented Nov 28, 2019 at 11:34
  • 1
    I think it's just because lightning:input is a universal component that can return many data types including strings and even arrays. So I've seen some weird casting artifacts happen. What I'd suggest is, before sending to Apex, use the JS Number() function to change the string decimals into proper numbers. Then Apex will receive it without ambiguity.
    – Charles T
    Commented Nov 28, 2019 at 12:52

1 Answer 1

2

I think it's just because lightning:input is a universal component that can return many data types including strings and even arrays. So I've seen some weird casting artifacts happen. What I'd suggest is, before sending to Apex, use the JS Number() function to change the string decimals into proper numbers. Then Apex will receive it without ambiguity.

1
  • I noticed one number being multiplied by 1.000.000.000.000 when being passed from Javascript to Apex. Converting via Number() in JS solved the problem. Commented Jul 10 at 10:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .