0

I have a very heavy JSON response from an external webservice. I am parsing the JSON response and binding it to a jQuery plugin called 'Dynatree' to show the same in a tree structure on a VF page.

Does 'Too many code statements' include javascript statements too? or its just the Apex statements? Please advice.

Thanks /Roshan

 public void generateTree(String JSONResponse){  
    integer totalCalls = 0;  
    JSONString = '';  
    String startTime = '';                    
    String duration = '';                 
    String amount = '';
    String usagetype = '';
    noRecords = false;            
    usageList = new List<UsageTree>();
    //String visAlt = '';

    try{
        Map<String, Object> firstMap = (Map<String, Object>)JSON.deserializeUntyped(JSONResponse);
        Map<String, Object> rootDataMap;
        System.debug('717 First Map '+ firstMap); 

        if(firstMap != null && firstMap.get('usage') != null){
            firstMap = (Map<String, Object>)firstMap.get('usage');
            visAlt = String.valueOf(firstMap.get('amount'));
            visAlt = currency(visAlt); //CARRIE-963
            String calls = String.valueOf(firstMap.get('calls'));
            rootDataMap = (Map<String, Object>)firstMap.get('data');
            //System.debug('717 First Map 1 '+ rootDataMap);

            for(String rootDataNode : rootDataMap.keySet()){
             String userNumber = rootDataNode;              


            Pattern valid_characters = Pattern.compile('([0-9]+)'); 
            firstMap = (Map<String, Object>)rootDataMap.get(userNumber); 
            firstMap = (Map<String, Object>)firstMap.get('data');
            //firstMap now contains main nodes (eg: Opkald til Danmark, Opkald til servicenumre, Opkaldsafgift, Opkaldsforsøg)
            for(String mainNodes : firstMap.keySet()){
                Map<String, Object> secondMap = (Map<String, Object>)firstMap.get(mainNodes);  
                //secondMap contains child nodes (eg: Opkald til Mobil)
                String mainCalls = String.valueOf(secondMap.get('calls'));
                String mainAmount = String.valueOf(secondMap.get('amount'));
                mainAmount = currency(mainAmount);     
                String parentType =  mainCalls + ' stk ' + mainNodes;     
                JSONString += '{title : "<span class=\'td2_1\'>' +parentType+ '</span><span class=\'td2_2\'>' +mainAmount+ '</span>#"';                                             
                String thirdMapString = String.valueOf(secondMap.get('data'));
                //For scenarios with no child nodes eg: debiting, crediting
                if(thirdMapString.indexOf('(') == 0){
                    List<Object> thirdMapList = (List<Object>)secondMap.get('data');
                    Integer thirdListCount = 0;
                    for(Object o : thirdMapList){
                        Map<String, Object> mappp = (Map<String, Object>)o;
                        startTime = String.valueOf(mappp.get('start-time'));
                        duration = String.valueOf(mappp.get('duration'));
                        amount = String.valueOf(mappp.get('amount')); 
                        amount = currency(amount); 
                        usagetype = String.valueOf(mappp.get('usagetype')); 
                        thirdListCount++;
                        if(thirdListCount == thirdMapList.size())
                            JSONString += '{title : "<span class=\'td4_1\'>'+startTime+'</span><span class=\'td4_2\'>'+usagetype+'</span><span class=\'td4_3\'>'+duration+'</span><span class=\'td4_4\'>'+amount+'</span>^"}';
                        else
                            JSONString += '{title : "<span class=\'td4_1\'>'+startTime+'</span><span class=\'td4_2\'>'+usagetype+'</span><span class=\'td4_3\'>'+duration+'</span><span class=\'td4_4\'>'+amount+'</span>^"},';   



                        //Add to Usage List
                        UsageTree uTObj = new UsageTree();
                        uTObj.callToNumber = mainNodes;  
                        uTObj.numberForEmail = mainNodes;                                                                 
                        uTObj.startDate = startTime;
                        uTObj.duration = duration;                           
                        uTObj.amount = amount;
                        usageList.add(uTObj);                                                   

                        //create a map for string and dateTime
                        integer index = startTime.indexOf(' ');
                        string dateString = startTime.subString(0,index);
                        string timeString = startTime.subString(index+1);
                        List<String> dList = dateString.split('-');
                        List<String> timeList = timeString.split(':');
                        string stringDate = dList[2] + '-' + dList[1] + '-' + dList[0] + 
                            ' ' + timeList[0] + ':' + timeList[1] +  ':' + timeList[2];
                        Datetime Dt = datetime.valueOf(stringDate); 
                        stringDateMap.put(startTime,Dt);   
                    }  
                } 
                else{ 
                    Map<String, Object> thirdMap = (Map<String, Object>)secondMap.get('data');     
                    //System.debug('thirdMap 717: '+thirdMap);         
                    Integer thirdNodesCount = 0;
                    JSONString += ', children : [';                 
                    for(String thirdNodes : thirdMap.keySet()){                 
                        Map<String, Object> fourthMap = (Map<String, Object>)thirdMap.get(thirdNodes);  
                        mainCalls = String.valueOf(fourthMap.get('calls'));
                        parentType =  mainCalls + ' stk ' + thirdNodes; 
                        if(!parentType.contains('Opkaldsafgift') && !parentType.contains('Opkaldsforsøg')){
                            JSONString += '{title : "'+parentType+'#"'+ 
                                 ', children : [' ;                                  
                        }                        
                        if(fourthMap.get('data') != null){
                            fourthMap = (Map<String, Object>)fourthMap.get('data');                     
                            Integer fourthNodesCount = 0;
                            for(String fourthNodes : fourthMap.keySet()){
                                Matcher check_chars = valid_characters.matcher(fourthNodes);
                                if(check_chars.matches()){
                                    Map<String, Object> fifthMap = (Map<String, Object>)fourthMap.get(fourthNodes); 
                                    mainCalls = String.valueOf(fifthMap.get('calls'));

                                    String callToNumberSummary = '';
                                    String numberForEmail = '';
                                    String callToNumber = '';

                                    //Add * at end for email
                                    Integer numLength = fourthNodes.length();
                                    numberForEmail = fourthNodes;
                                    if(fourthNodes.length()>4)
                                        numberForEmail = fourthNodes.subString(0,4);
                                    for(integer no=0;no<numLength-4;no++){
                                        numberForEmail+='*';
                                    }                                        
                                    System.debug('ThirdNode'+ thirdNodes);
                                    //Create different strings for different display
                                    if(thirdNodes.contains(' ')){
                                        integer lastindex = thirdNodes.lastIndexOf(' ');
                                        callToNumber = mainCalls + ' stk ' + thirdNodes.subString(0,lastindex) + ' ' + fourthNodes;
                                        callToNumberSummary = thirdNodes.subString(0,lastindex) + ' ' +fourthNodes;                             
                                        //numberForEmail = thirdNodes.subString(0,lastindex) + ' ' +numberForEmail;                     
                                    }else{

                                        callToNumber = mainCalls + ' stk ' + thirdNodes + ' ' + fourthNodes;
                                        callToNumberSummary = thirdNodes + ' ' +fourthNodes;                             


                                    }                                                                                   

                                    JSONString += '{title : "'+callToNumber+'#"';
                                    JSONString += ', children : ['; 

                                    JSONString += '{title : "<span class=\'td4_1\'>Dato</span><span class=\'td4_2\'>Beskrivelse</span><span class=\'td4_3\'>Varighed</span><span class=\'td4_4\'>Pris i dkk.</span>#",addClass:"colored"},';
                                    List<Object> fifthList = (List<Object>)fifthMap.get('data');    
                                    Integer fifthListCount = 0;
                                    for(Object o : fifthList){
                                        Map<String, Object> mappp = (Map<String, Object>)o;
                                        startTime = String.valueOf(mappp.get('start-time'));
                                        duration = String.valueOf(mappp.get('duration'));
                                        amount = String.valueOf(mappp.get('amount')); 
                                        usagetype = String.valueOf(mappp.get('usagetype'));
                                        amount = currency(amount);  
                                        fifthListCount++;
                                        if(fifthListCount==fifthList.size())
                                            JSONString += '{title : "<span class=\'td4_1\'>'+startTime+'</span><span class=\'td4_2\'>'+usagetype+'</span><span class=\'td4_3\'>'+duration+'</span><span class=\'td4_4\'>'+amount+'</span>^"}';
                                        else
                                            JSONString += '{title : "<span class=\'td4_1\'>'+startTime+'</span><span class=\'td4_2\'>'+usagetype+'</span><span class=\'td4_3\'>'+duration+'</span><span class=\'td4_4\'>'+amount+'</span>^"},';  



                                        //system.debug(mainNodes + ' : ' + thirdNodes + ' : ' + fourthNodes + ' : ' + startTime + ' : ' + duration  + ' : ' + amount);
                                        system.debug('numberForEmail: '+numberForEmail);
                                        //Add to Usage List
                                        UsageTree uTObj = new UsageTree();
                                        //uTObj.callToNumber = callToNumberSummary;    
                                        uTObj.callToNumber = usagetype + ' ' +fourthNodes;  
                                        //uTObj.numberForEmail = numberForEmail;  
                                        uTObj.numberForEmail = usagetype + ' ' +numberForEmail;                                                          
                                        uTObj.startDate = startTime;
                                        uTObj.duration = duration;                           
                                        uTObj.amount = amount;
                                        usageList.add(uTObj);                                                   

                                        //create a map for string and dateTime
                                        integer index = startTime.indexOf(' ');
                                        string dateString = startTime.subString(0,index);
                                        string timeString = startTime.subString(index+1);
                                        List<String> dList = dateString.split('-');
                                        List<String> timeList = timeString.split(':');
                                        string stringDate = dList[2] + '-' + dList[1] + '-' + dList[0] + 
                                            ' ' + timeList[0] + ':' + timeList[1] +  ':' + timeList[2];
                                        Datetime Dt = datetime.valueOf(stringDate); 
                                        stringDateMap.put(startTime,Dt);   
                                    }  
                                    fourthNodesCount++;                                                                     
                                    if(fourthNodesCount == fourthMap.size() && thirdNodesCount+1 == thirdMap.size())
                                        JSONString += ']}';                                                                            
                                    else
                                        JSONString += ']},';                                                                                                    
                                }
                            }
                        }
                        thirdNodesCount++; 
                        if(!parentType.contains('Opkaldsafgift') && !parentType.contains('Opkaldsforsøg')) {
                            if(thirdNodesCount == thirdMap.size())
                                JSONString += ']}';
                            else
                                JSONString += ']},';                                   
                        }                    
                    }                        
                }   
                JSONString += ']},';            
            }   
        }
  }
  • Can we get your apex code so that we can exactly point why we are having too many code script statements? – Mohith Shrivastava Aug 10 '13 at 6:56
  • I have posted my code. Can you please help. Thanks – Roshan Sahatiya Aug 10 '13 at 12:20
  • Please post the JSON also.I think you have complicated so much with lot of for loops .Also delete the code from your answer.I have added code in your question itself. – Mohith Shrivastava Aug 10 '13 at 13:17
  • Mohith, I am not able to post JSON as it exceeds the limit allowed here. Can you I email you? Thanks – Roshan Sahatiya Aug 10 '13 at 14:12
  • Please host it somewhere in free file sharing website or gist of github and please also explain like how the tree structure will be .There are other people in this site who may also like to look and they may help from previous experience – Mohith Shrivastava Aug 10 '13 at 17:01
4

There is a quadruply nested for loop in the code. That is probably the cause, you can verify this by looking at debug logs. You can fix this by flattening out your loops and using maps.

As mulveling pointed out, javascript runs on the client and does not consume script statements. It may be best to use this to your advantage, and instead of parsing this json string on the server, do it on the client before feeding it into Dynatree. Furthermore, this may be a good idea because JSONString may be large enough such that you start hitting other governor limits.

| improve this answer | |
  • In the next release, they're removing the 200,000 line limit. You'll be able to do as much work as you can do in 600,000 ms of server time, which may help. Also, the built-in JSON builder classes could be used to build the constructs far faster and with only a few lines of script. – sfdcfox Sep 20 '13 at 14:22
2

No, Javascript statements execute client-side (in the browser) and will not count against your Apex script statements limit. However, JSON is not Javascript -- if your JSON parsing is occurring server-side (in Apex), and you're using something other than Apex's native JSON.deserialize method (or better yet, JSON.deserializeUntyped), then it may gobble up your script statements all too quickly. Unfortunately, parsers/lexers optimized for traditional platforms (e.g. Java, C++, etc) will often be unusable when ported to Apex, due to its unorthodox script-statements limit. If you could post the offending code, then I (or others) may be able to point you towards a more specific solution.

| improve this answer | |
  • I have posted my code. Can you please help? Also the parsing as you mentioned is happening server side in the Apex code. I am using JSON.deserializeUntyped. You can see the same in the code posted. Thanks – Roshan Sahatiya Aug 10 '13 at 12:20

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.