0

When deserializing a JSON-serialized Apex object, received from a Lightning component, I'm getting the following error:

FATAL_ERROR System.JSONException: N/A at [line:1, column:155]

Data class:

global class SomeClass {
    @AuraEnabled
    global Decimal someField { get; set; }
}

Server-side Lightning controller:

@AuraEnabled
global static void someMethod(String objJson) {
    System.debug(objJson); // {"someField":""}
    SomeClass obj = (SomeClass)JSON.deserialize(objJson, SomeClass.class); // throws exception
}

Client-side Lightning controller:

"callServer" : function(component) {
    var obj = component.get("v.obj");
    obj.someField = valueFromInput; // an HTML input element

    var serverAction = component.get("c.someMethod");
    serverAction.setParams({ "objJson" : JSON.stringify(obj) });
    $A.enqueueAction(serverAction);
}
  • My original case had a lot more fields than the one Decimal shown here, so it wasn't as obvious that one of the JSON properties had a value with wrong type. :) – neonblitzer Nov 20 '17 at 16:21
1

String values for numeric fields cause this error—even empty strings!

It's easy to make this mistake when grabbing the value from an HTML input in Lightning. The value of an empty input is the empty string, not null or undefined. If the value should be deserialized into a numeric data type, you must make sure to do validation not just for illegal non-empty values, but for empty values too.

// example just to illustrate the point
var validatedValue = valueFromInput !== "" ? valueFromInput : null;
obj.someField = validatedValue;

That said, the Salesforce error message is quite useless. Type mismatch should be pretty easy to report.

  • For this reason, you should be using attributes, not raw HTML input elements. Yes, you can do so, but you're really just making more work for yourself. Also, this is JavaScript: obj.someField = valueFromInput || null; – sfdcfox Nov 20 '17 at 16:42
  • @sfdcfox 0 || null evaluates to null, even though 0 is valid for numerical input. About attributes—yeah, true enough, although sometimes the component might be large or dynamic enough to make using component attributes cumbersome. – neonblitzer Nov 20 '17 at 16:50
  • Yeah, actually, I suppose you'd almost want to parseInt instead. Still, when you get down to it, you should still consider using attributes. Yes, they're more cumbersome, but you get automatic input validation. There's a benefit for the cost of admission. – sfdcfox Nov 20 '17 at 16:53
  • @sfdcfox The validation in this example is indeed very simple, and the answer does disclose that because what you'd want to actually do depends entirely on your application. :) – neonblitzer Nov 20 '17 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.