0

Im collecting data via Salesforce inbound email services. I am sending data in json format : { "some_field" : "some_field_value"} with multiple fields.

Im using this code to make the insert:

NPS__c response = new NPS__c();
            
Map<String, String> m = (Map<String,String>) JSON.deserialize(JSON_from_email, map<String,String>.class);
for (String f : m.keySet()) {
    response.put(f, m.get(f));
}
insert response; 

where 'JSON_from_email' is obtained by getting the plain text body of an inbound email.

my problem is that one of the fields is an number field { "some_field" : 100 }.

This code fails " Illegal assignment from string to decimal"

I know what the problem is, this produces a string:

JSON.deserialize(splitted_surveys, map<String,String>.class);

how can i change this so that one specific value of the JSON becomes a number?

thanks!

1

Use JSON.deserializeUntyped instead (this gives you Map<String, Object> instead):

NPS__c response = new NPS__c();
Map<String, Object> m = (Map<String,Object>) JSON.deserializeUntyped(JSON_from_email);
for (String f : m.keySet()) {
  response.put(f, m.get(f));
}
insert response; 

Also, if the payload already has the correct format, you should also be able to:

NPS__c response = (NPS__c)JSON.deserialize(JSON_from_email, NPS__c.class);
insert response;

The latter automatically supports most field types, including Date, Time, Boolean, Numbers, and Strings.

3
  • To add to sfdcfox's answer. You are getting this error because you are trying to cast incompatible data to Map<String, String>. This means that one of the values in your map is not a string. Specifically {"some_field": 100}. JSON has four primitive data types (String, Number, Boolean and null). When you deserialize, these values get converted to their respective types in Apex (even if using deserializeUntyped). This is the reason why you cannot cast a JSON value to Map<String, String>, some of the values contained in that JSON data aren't strings. – adriancg Jul 20 '20 at 18:26
  • @adriancg Actually, JSON.deserialize uses the class as a hint, and it's trying to deserialize the number 100 as a String, which it cannot, so it fails. You actually can't cast JSON.deserializeUntyped to a Map<String, String> reliably. It fails before the cast even happens in the OP code. – sfdcfox Jul 20 '20 at 18:31
  • thanks for the clarification. So it fails at a different point then. The error message kind of clashes with my mental model of what happens under the hood, since I would think you're trying to assign a Decimal to a String and not the other way around. I guess the bottom line is use Map<String, Object> with deserializeUntyped to avoid runtime errors. – adriancg Jul 20 '20 at 18:40

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.