function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
gaurav.sfdcgaurav.sfdc 

Illegal value for primitive (JSON.deserialize crashing with currency field)

I am using analytics API. I parse resuting Json through Report Parser Class. This worked when there is no currency field selected. As soon as I fetch currency field in report. This parser class gets crashed with message "Illegal value for primitive" at line

reportData = (ReportWrapper)JSON.deserialize(jsonString, ReportWrapper.class);

Please find below both Parser class and Json string with currency field which when passed gets crashed.
Could you please help me modifying the parser class to accomodate currency field
(There is also some difference for currency fields and other fields which comes like array/object -- see below vs normal field
Currency = {"label":"$10.00","value":{"amount":10,"currency":null}},
Normal field = {"label":"1/11/2015","value":"2015-01-11"} )

public static ReportWrapper parseReport(String reportId){
        Http http = new Http();
        HttpRequest httpReq = new HttpRequest();
        HttpResponse httpRes = new HttpResponse();
       
        httpReq.setMethod('GET');
        httpReq.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
        httpReq.setEndpoint( getAnalyticAPIEndpoint(reportId) );
        
        String jsonString = '';

        jsonString = httpRes.getBody();
        jsonString = jsonString.left(jsonString.indexOf('T!T'))+'tXXXXXt'+jsonString.subString(jsonString.indexOf('T!T')+3,jsonString.length());
        System.debug('@@@@@@@@@@@@Body : jsonString :' +jsonString);
        //jsonString = jsonString.replaceAll('T!T','tXXXXXt');
        ReportWrapper reportData;
        try{
           reportData = (ReportWrapper)JSON.deserialize(jsonString, ReportWrapper.class);
        }catch(Exception e){
            System.debug(e.getMessage() + ' : StackTrace ' + e.getStackTraceString());
        }
        System.debug('@@@@@@@Report Data after parsing: '+reportData);
        
        
       
         ReportDataWrapper factMap = (ReportDataWrapper)JSON.deserialize(jsonString, ReportDataWrapper.class);
         System.debug('@@@@@>>     '+factMap);
        //httpRes.getBody();*/
        return reportData;
    }
 public class ReportWrapper{
        public boolean hasDetailRows{set; get;}
        public ReportAttributesWrapper attributes{set; get;}
        public GroupingWrapper groupingsDown{set; get;}
        public GroupingWrapper groupingsAcrosss{set; get;}
        public ReportDataWrapper factMap{set; get;}
        //public Map<String, NewTableWrapper> factMap{set; get;}
        public boolean allData{set; get;}
        public ExtendedMetadataWrapper reportExtendedMetadata{set;get;}
        public MetadataWrapper reportMetadata{set; get;}
    }
    
    public class ReportAttributesWrapper{
        public String instancesUrl {set; get;}
        public String describeUrl {set; get;}
        public String type {set; get;}
        public String reportId {set; get;}
        public String reportName {set; get;}
    }
    public class GroupingWrapper{
        public List<String> groupings{set; get;}
    }
    public class ReportDataWrapper{
        public NewTableWrapper tXXXXXt{set; get;}
    }
    public class NewTableWrapper{
        public List<RowWrapper>rows{set; get;}
        public List<AggregateWrapper> aggregates{set; get;}
    }
    public class TableWrapper{
        public List<RowWrapper> rows{set; get;}
        public CellWrapper aggregates{set; get;}
    }
    public class RowWrapper{
        public List<CellWrapper> dataCells{set; get;}
    }
    public class CellWrapper{
        public String value{set; get;}
        public String Label{set; get;}
    }
    public class AggregateWrapper{
        public long value{set; get;}
        public String label{set; get;}
    }
    public class ExtendedMetadataWrapper{
        public Map<String,ColumnInfo> detailColumnInfo{set; get;}
        public Map<String,Map<String,String>> aggregateColumnInfo{set; get;} 
        public GroupingColumnInfo groupingColumnInfo{set;get;}
    }
    public class ColumnInfo{
        public String dataType{set; get;}
        public String label{set; get;}
    }
    public class MetadataWrapper{
        public String Name{set;get;}
        public String id{set;get;}
        public List<String> aggregates{set; get;}
        public List<GroupingWrapper> groupingsDown{set; get;}
        public List<GroupingWrapper> groupingsAcross{set; get;}
        public boolean reportBooleanFilter{set;get;}
        public List<FilterWrapper> reportFilters{set; get;}
        public List<String> detailColumns{set; get;}
        public String developerName{set; get;}
        public ReportType reportType{set; get;}
        public String currencyValue{set; get;}
        public String reportFormat{set; get;}
    }
    
    public class FilterWrapper{
        public String value{set; get;}
        public String column{set; get;}
        public String operator{set; get;}
    }
    public class ReportType{
        public String type{set; get;}
        public String label{set; get;}
    }
    public class GroupingColumnInfo{
        
    }
 

JSON String:

{"attributes":{"describeUrl":"/services/data/v29.0/analytics/reports/00OC00000065lGJMAY/describe","instancesUrl":"/services/data/v29.0/analytics/reports/00OC00000065lGJMAY/instances","reportId":"00OC00000065lGJMAY","reportName":"my report","type":"Report"},"allData":true,"factMap":{"tXXXXXt":{"aggregates":[{"label":"2","value":2}],"rows":[{"dataCells":[{"label":"006C000000qCLto","value":"006C000000qCLtoIAG"},{"label":"Op2","value":"006C000000qCLtoIAG"},{"label":"-","value":null},{"label":"1/31/2015","value":"2015-01-31"},{"label":"-","value":null},{"label":"Prospecting","value":"Prospecting"},{"label":"10%","value":10},{"label":"Q1-2015","value":"Q1-2015"},{"label":"185","value":185},{"label":"7/13/2014","value":"2014-07-14"},{"label":"Nikhil Jain Dev","value":"005C000000609M2IAI"},{"label":"-","value":null},{"label":"Simplion","value":"001C000001FeLDvIAN"}]},{"dataCells":[{"label":"006C000000w65py","value":"006C000000w65pyIAA"},{"label":"Op1","value":"006C000000w65pyIAA"},{"label":"$10.00","value":{"amount":10,"currency":null}},{"label":"1/11/2015","value":"2015-01-11"},{"label":"-","value":null},{"label":"Qualification","value":"Qualification"},{"label":"10%","value":10},{"label":"Q1-2015","value":"Q1-2015"},{"label":"7","value":7},{"label":"1/7/2015","value":"2015-01-07"},{"label":"Nikhil Jain Dev","value":"005C000000609M2IAI"},{"label":"-","value":null},{"label":"Deimple Acnt","value":"001C000001HP9P5IAL"}]}]}},"groupingsAcross":{"groupings":[]},"groupingsDown":{"groupings":[]},"hasDetailRows":true,"reportExtendedMetadata":{"aggregateColumnInfo":{"RowCount":{"acrossGroupingContext":null,"dataType":"int","downGroupingContext":null,"label":"Record Count"}},"detailColumnInfo":{"OPPORTUNITY_ID":{"dataType":"id","label":"Opportunity ID"},"OPPORTUNITY_NAME":{"dataType":"string","label":"Opportunity Name"},"EXP_AMOUNT":{"dataType":"currency","label":"Expected Revenue"},"CLOSE_DATE":{"dataType":"date","label":"Close Date"},"NEXT_STEP":{"dataType":"string","label":"Next Step"},"STAGE_NAME":{"dataType":"picklist","label":"Stage"},"PROBABILITY":{"dataType":"percent","label":"Probability (%)"},"FISCAL_QUARTER":{"dataType":"string","label":"Fiscal Period"},"AGE":{"dataType":"int","label":"Age"},"CREATED_DATE":{"dataType":"datetime","label":"Created Date"},"FULL_NAME":{"dataType":"string","label":"Opportunity Owner"},"ROLLUP_DESCRIPTION":{"dataType":"string","label":"Owner Role"},"ACCOUNT_NAME":{"dataType":"string","label":"Account Name"}},"groupingColumnInfo":{}},"reportMetadata":{"aggregates":["RowCount"],"currency":null,"detailColumns":["OPPORTUNITY_ID","OPPORTUNITY_NAME","EXP_AMOUNT","CLOSE_DATE","NEXT_STEP","STAGE_NAME","PROBABILITY","FISCAL_QUARTER","AGE","CREATED_DATE","FULL_NAME","ROLLUP_DESCRIPTION","ACCOUNT_NAME"],"developerName":"my_report","groupingsAcross":[],"groupingsDown":[],"id":"00OC00000065lGJMAY","name":"my report","reportBooleanFilter":null,"reportFilters":[],"reportFormat":"TABULAR","reportType":{"label":"Opportunities","type":"Opportunity"}}}
Best Answer chosen by gaurav.sfdc
gaurav.sfdcgaurav.sfdc
Thanks Kevin but replacing $ won't work as the sign is not creating problem. The problem is, for currency, the value part is retrieved as object and not as string i.e. "value":{"amount":10,"currency":null}}

Now I got the workaround for this : Since I don't need this value I simply find 'currency' and get the substring like '{"amount":10,"currency":null}'. Now I replace this substring with "" and this worked for me. I looped it for all such type of occurence. There may be some more optimized way but I am putting the code below to give others some idea looking for similar thing

       integer J1 = jsonString.indexOf('currency') ;
        while (J1 != -1){
             integer J2;
             integer J3;
             if(J1 != -1)
             {
                 J2 = jsonString.indexOf('value',(J1-30))+7 ;// {
                if(J2 != -1){
                     J3 = jsonString.indexOf('}',J2) ;// }
                     String str = jsonString.substring(J2,J3+1);
                    if(str.contains('currency'))
                    {
                        //System.debug('J1 ' + J1);
                        //System.debug('J2 ' + J2);
                        //System.debug('J3 ' + J3);
                        System.debug('substr ' + str);
                        jsonString = jsonString.replace(str,'\"\"');
                      }
                else{
                    break;
                }
            
            }
            J1 = jsonString.indexOf('currency') ;
        }
        
     }

All Answers

KevinPKevinP
you're going to need to regex replace the $ out of your json string before parsing or deserialize untyped the string,
gaurav.sfdcgaurav.sfdc
Thanks Kevin but replacing $ won't work as the sign is not creating problem. The problem is, for currency, the value part is retrieved as object and not as string i.e. "value":{"amount":10,"currency":null}}

Now I got the workaround for this : Since I don't need this value I simply find 'currency' and get the substring like '{"amount":10,"currency":null}'. Now I replace this substring with "" and this worked for me. I looped it for all such type of occurence. There may be some more optimized way but I am putting the code below to give others some idea looking for similar thing

       integer J1 = jsonString.indexOf('currency') ;
        while (J1 != -1){
             integer J2;
             integer J3;
             if(J1 != -1)
             {
                 J2 = jsonString.indexOf('value',(J1-30))+7 ;// {
                if(J2 != -1){
                     J3 = jsonString.indexOf('}',J2) ;// }
                     String str = jsonString.substring(J2,J3+1);
                    if(str.contains('currency'))
                    {
                        //System.debug('J1 ' + J1);
                        //System.debug('J2 ' + J2);
                        //System.debug('J3 ' + J3);
                        System.debug('substr ' + str);
                        jsonString = jsonString.replace(str,'\"\"');
                      }
                else{
                    break;
                }
            
            }
            J1 = jsonString.indexOf('currency') ;
        }
        
     }
This was selected as the best answer