0

Im trying to get values from API request.. there`s 2 user data from the response and I want to get the data of each user and put it on the list.. but my code only store the last user data from the response and abandon the other one..

this is my code

for (User us : userSF){          
        Purecloud__c ipcccc = new Purecloud__c();
        ipcccc.Name = us.Name+'_'+year+'-'+month+'-'+day;
        ipcccc.Agent__c = '-';
        ipcccc.Agent_Name__c = us.Id;
        ipcccc.Queue_Group__c = 'AFI';
        ipcccc.External_ID__c = us.SIP__c+'_'+year+'-'+month+'-'+day;
        ipcccc.Date__c = date.valueof(startInterval);
        ipcccc.Type__c = 'Daily';
        tempAgent.add(ipcccc);
    }


    String JSONstring = '{  "interval": "'+startInterval+'/'+endInterval+'",  "timeZone": "Asia/Jakarta",  "groupBy": [   "userId"  ],  "filter": {   "type": "or",   "predicates": [';
    String bodypart1 = '{"type":"dimension","dimension":"userId","operator":"matches","value":"';
    String bodypart2 = '"}';
    String endString = ']  },  "metrics": [   "tSystemPresence"  ] }';
    String comma = ',';
    Integer sizeUser = userSF.size();

    for (integer i = 0; i < sizeUser; i++){
        JSONstring += bodypart1 + userSF[i].SIP__c + bodypart2;
        if(i + 1 < sizeUser){
            JSONstring += comma;
        }
    }
    JSONstring += endString;
    System.debug('jsonString = ' + jsonString);


    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(url);
    req.setMethod('POST');
    req.setTimeout(120000);
    req.setHeader('content-type', 'application/json');
    req.setHeader('Authorization', 'Bearer '+ token);
    req.setBody(JSONstring);

    try{
        HttpResponse res = new HttpResponse();
        res = h.send(req);
            JSONParser parser;
            if (test.isRunningTest()==false) parser = JSON.createParser(res.getBody());
            system.debug('*body*'+parser);
                while (parser.nextToken() != null) {
                    if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
                        while (parser.nextToken() != JSONToken.END_ARRAY) {
                        if (parser.getText() == 'userId' && parser.nextToken() != null){ 
                                purecloudid = parser.getText();
                                system.debug('*id*'+parser.getText()); 

                        } 
                            else if (parser.getText() == 'qualifier'){
                                parser.nextToken();
                                status = parser.getText();
                                    if(parser.getText() == 'AVAILABLE') { //AVAILABLE
                                    system.debug('Status Available ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    system.debug('CURRENT POSITION ==>'+parser.getText());
                                    parser.nextToken();
                                    availableSec = parser.getText();

                                    system.debug('Available Second ==>'+parser.getText());
                                    system.debug('String ava ==>'+availableSec);
                                        }
                                    if(parser.getText() == 'AWAY') { //AWAY
                                    system.debug('Status AWAY ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    awaySec = parser.getText();

                                    system.debug('AWAY Second ==>'+parser.getText());
                                    system.debug('String AWAY ==>'+awaySec);
                                        }
                                    if(parser.getText() == 'MEETING') { //MEETING
                                    system.debug('Status MEETING ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    meetingSec = parser.getText();

                                    system.debug('MEETING Second ==>'+parser.getText());
                                    system.debug('String MEETING ==>'+meetingSec);
                                        }
                                    if(parser.getText() == 'TRAINING') { //TRAINING
                                    system.debug('Status TRAINING ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    trainingSec = parser.getText();

                                    system.debug('TRAINING Second ==>'+parser.getText());
                                    system.debug('String TRAINING ==>'+trainingSec);
                                        }
                                    if(parser.getText() == 'BUSY') { //BUSY
                                    system.debug('Status BUSY ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    busySec = parser.getText();

                                    system.debug('BUSY Second ==>'+parser.getText());
                                    system.debug('String BUSY ==>'+busySec);
                                        }
                                    if(parser.getText() == 'BREAK LUNCH') { //BREAK LUNCH
                                    system.debug('Status BUSY ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    breakLunchSec = parser.getText();

                                    system.debug('breakLunchSec Second ==>'+parser.getText());
                                    system.debug('String breakLunchSec ==>'+breakLunchSec);
                                        }
                                    if(parser.getText() == 'BREAK PRAY') { //BREAK PRAY
                                    system.debug('Status BUSY ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    breakPraySec = parser.getText();

                                    system.debug('breakPraySec Second ==>'+parser.getText());
                                    system.debug('String breakPraySec ==>'+breakPraySec);
                                        }
                                    if(parser.getText() == 'BREAK REST') { //BREAK REST
                                    system.debug('Status BUSY ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    breakRestSec = parser.getText();

                                    system.debug('breakRestSec Second ==>'+parser.getText());
                                    system.debug('String breakRestSec ==>'+breakRestSec);
                                        }
                                    if(parser.getText() == 'BREAK OTHER') { //BREAK OTHER
                                    system.debug('Status BUSY ==>'+ parser.getText());
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    parser.nextToken();
                                    breakOtherSec = parser.getText();

                                    system.debug('breakOtherSec Second ==>'+parser.getText());
                                    system.debug('String breakOtherSec ==>'+breakOtherSec);
                                        }
                                }
                        }
                    }   
                        agentAPI1.SIP__c = purecloudid;
                        agentAPI1.External_ID__c = purecloudid+'_'+year+'-'+month+'-'+day; 
                        agentAPI1.Available_Sum__c = Decimal.valueof(Integer.valueof(availableSec)/1000);
                        agentAPI1.Away_Sum__c = Decimal.valueof(Integer.valueof(awaySec)/1000);
                        agentAPI1.Meeting_Sum__c = Decimal.valueof(Integer.valueof(meetingSec)/1000);
                        agentAPI1.Training_Sum__c = Decimal.valueof(Integer.valueof(trainingSec)/1000);
                        agentAPI1.Break_Lunch_Sum__c = Decimal.valueof(Integer.valueof(breaklunchSec)/1000);
                        agentAPI1.Busy_Sum__c = Decimal.valueof(Integer.valueof(busySec)/1000);
                        agentAPI1.Break_Pray_Sum__c = Decimal.valueof(Integer.valueof(breakpraySec)/1000);
                        agentAPI1.Break_Rest_Sum__c = Decimal.valueof(Integer.valueof(breakrestSec)/1000);
                        agentAPI1.Break_Other_Sum__c = Decimal.valueof(Integer.valueof(breakotherSec)/1000);
                        upsertAPI1.add(agentAPI1); 

                }
                    Set<Purecloud__c> myset = new Set<Purecloud__c>();
                    List<Purecloud__c> resultAPI1 = new List<Purecloud__c>();
                    myset.addAll(upsertAPI1);
                    resultAPI1.addAll(myset);   
                    string s = '';
                    for (Object r : resultAPI1) s += '\n' + r;
                    system.debug('resultAPI1 ==>'+s);

                    //if(tempAgent.size()>0) upsert tempAgent External_ID__c;
                    //if(upsertAPI1.size()>0) upsert resultAPI1 External_ID__c;

    }   
    catch(exception e){
        system.debug('*error*'+e);
    }

enter image description here
as you can see theres 2 user data, but theres only 1 user data saved on list..

this is the response

{ "results": [ { "group": { "userId": "4f798b1d-d27a-4415-b793-02b420586e73" }, "data": [ { "interval": "2018-10-01T01:00:00.000Z/2018-10-07T01:00:00.000Z", "metrics": [ { "metric": "tSystemPresence", "qualifier": "AVAILABLE", "stats": { "sum": 295693992 } }, { "metric": "tSystemPresence", "qualifier": "OFFLINE", "stats": { "sum": 222706008 } } ] } ] }, { "group": { "userId": "ab24ddb8-f1ef-4cca-ae72-9f20f5975332" }, "data": [ { "interval": "2018-10-01T01:00:00.000Z/2018-10-07T01:00:00.000Z", "metrics": [ { "metric": "tSystemPresence", "qualifier": "AWAY", "stats": { "sum": 949 } }, { "metric": "tSystemPresence", "qualifier": "MEAL", "stats": { "sum": 2409 } }, { "metric": "tSystemPresence", "qualifier": "MEETING", "stats": { "sum": 31909 } }, { "metric": "tSystemPresence", "qualifier": "AVAILABLE", "stats": { "sum": 216862072 } }, { "metric": "tSystemPresence", "qualifier": "OFFLINE", "stats": { "sum": 301492112 } }, { "metric": "tSystemPresence", "qualifier": "TRAINING", "stats": { "sum": 7885 } }, { "metric": "tSystemPresence", "qualifier": "BUSY", "stats": { "sum": 1839 } }, { "metric": "tSystemPresence", "qualifier": "BREAK", "stats": { "sum": 825 } } ] } ] } ] }

1
  • Put that JSON into JSON2Apex and use the resulting code. Essentially you are then relying on a tool that has been widely used and tested instead of relying on once-off manual coding
    – Keith C
    Commented Oct 20, 2018 at 12:41

2 Answers 2

2

The class that makes JSON handling easy in Apex is the JSON Class. In many cases, the job can be made even simpler by using JSON2Apex to generate the related Apex code.

(JSONParser-based solutions require a lot of coding and are easy to get wrong. Also, JSON is best not created by concatenating strings as the resulting code is hard to get right, hard to read, and is often fragile in that it is missing the right escaping.)

The JSON class methods I most often use are:

  • JSON.serialize - serialize Apex nested arrays, maps and objects to JSON
  • JSON.serializePretty - similar, great for debug log output as nice formatting is done
  • JSON.deserializeUntyped - turn JSON into Apex nested arrays and maps
  • JSON.deserialize - turn JSON into Apex nested arrays, maps and objects (such as ones created by JSON2Apex)

The first thing to try is to get a reasonable sample of the JSON and run it through JSON2Apex. That might be "job done", as its output will be Apex arrays and objects that you can then just loop over and do whatever you need. Essentially rather than doing everything in one class, you will have separated out the problem to:

  • the JSON class walks around JSON or generates JSON
  • the JSON2Apex generated code represents the data model
  • your code is insulated from the details of JSON as it works using the data model

PS

Based on what you posted the sample JSON would be something like:

{
    "interval": "dynamicIntervalValue",
    "timeZone": "Asia/Jakarta",
    "groupBy": ["userId"],
    "filter": {
        "type": "or",
        "predicates": [
            {
                "type":"dimension",
                "dimension":"userId",
                "operator":"matches",
                "value":"dynamicSipValue"
            }
         ]
    },
    "metrics": ["tSystemPresence"]
}

and JSON2Apex generates the code listed below. (Note this code is usually simpler, but the presence of the "type" field in the JSON means a more complex pattern is needed.)

//
// Generated by JSON2Apex http://json2apex.herokuapp.com/
//
// The supplied json has fields with names that are not valid in apex
// and so can only be parsed with explicitly generated code, this option
// was auto selected for you.

public class JSON2Apex {

    public String interval {get;set;} 
    public String timeZone {get;set;} 
    public List<String> groupBy {get;set;} 
    public Filter filter {get;set;} 
    public List<String> metrics {get;set;} 

    public JSON2Apex(JSONParser parser) {
        while (parser.nextToken() != System.JSONToken.END_OBJECT) {
            if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                String text = parser.getText();
                if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                    if (text == 'interval') {
                        interval = parser.getText();
                    } else if (text == 'timeZone') {
                        timeZone = parser.getText();
                    } else if (text == 'groupBy') {
                        groupBy = arrayOfString(parser);
                    } else if (text == 'filter') {
                        filter = new Filter(parser);
                    } else if (text == 'metrics') {
                        metrics = arrayOfString(parser);
                    } else {
                        System.debug(LoggingLevel.WARN, 'JSON2Apex consuming unrecognized property: '+text);
                        consumeObject(parser);
                    }
                }
            }
        }
    }

    public class Filter {
        public String type_Z {get;set;} // in json: type
        public List<Predicates> predicates {get;set;} 

        public Filter(JSONParser parser) {
            while (parser.nextToken() != System.JSONToken.END_OBJECT) {
                if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                    String text = parser.getText();
                    if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                        if (text == 'type') {
                            type_Z = parser.getText();
                        } else if (text == 'predicates') {
                            predicates = arrayOfPredicates(parser);
                        } else {
                            System.debug(LoggingLevel.WARN, 'Filter consuming unrecognized property: '+text);
                            consumeObject(parser);
                        }
                    }
                }
            }
        }
    }

    public class Predicates {
        public String type_Z {get;set;} // in json: type
        public String dimension {get;set;} 
        public String operator {get;set;} 
        public String value {get;set;} 

        public Predicates(JSONParser parser) {
            while (parser.nextToken() != System.JSONToken.END_OBJECT) {
                if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                    String text = parser.getText();
                    if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                        if (text == 'type') {
                            type_Z = parser.getText();
                        } else if (text == 'dimension') {
                            dimension = parser.getText();
                        } else if (text == 'operator') {
                            operator = parser.getText();
                        } else if (text == 'value') {
                            value = parser.getText();
                        } else {
                            System.debug(LoggingLevel.WARN, 'Predicates consuming unrecognized property: '+text);
                            consumeObject(parser);
                        }
                    }
                }
            }
        }
    }


    public static JSON2Apex parse(String json) {
        System.JSONParser parser = System.JSON.createParser(json);
        return new JSON2Apex(parser);
    }

    public static void consumeObject(System.JSONParser parser) {
        Integer depth = 0;
        do {
            System.JSONToken curr = parser.getCurrentToken();
            if (curr == System.JSONToken.START_OBJECT || 
                curr == System.JSONToken.START_ARRAY) {
                depth++;
            } else if (curr == System.JSONToken.END_OBJECT ||
                curr == System.JSONToken.END_ARRAY) {
                depth--;
            }
        } while (depth > 0 && parser.nextToken() != null);
    }


    private static List<String> arrayOfString(System.JSONParser p) {
        List<String> res = new List<String>();
        if (p.getCurrentToken() == null) p.nextToken();
        while (p.nextToken() != System.JSONToken.END_ARRAY) {
            res.add(p.getText());
        }
        return res;
    }





    private static List<Predicates> arrayOfPredicates(System.JSONParser p) {
        List<Predicates> res = new List<Predicates>();
        if (p.getCurrentToken() == null) p.nextToken();
        while (p.nextToken() != System.JSONToken.END_ARRAY) {
            res.add(new Predicates(p));
        }
        return res;
    }


}

PPS

I took your result example, and generated a parser through JSON2Apex (using the class name MyParser) and then wrote this test clas to outline how the data can be accessed. You need to figure out the data structure you want to put the results into - I'm just adding to a simple string array. For each user there could be multiple intervals and for each interval there could be multiple metrics.

@IsTest
private class MyParserTest {

    @IsTest
    static void test() {

        // You can get this "compact" form that is easy to add to a test by using https://jsonformatter.curiousconcept.com/
        String jsonString = '{"results":[{"group":{"userId":"4f798b1d-d27a-4415-b793-02b420586e73"},"data":[{"interval":"2018-10-01T01:00:00.000Z/2018-10-07T01:00:00.000Z","metrics":[{"metric":"tSystemPresence","qualifier":"AVAILABLE","stats":{"sum":295693992}},{"metric":"tSystemPresence","qualifier":"OFFLINE","stats":{"sum":222706008}}]}]},{"group":{"userId":"ab24ddb8-f1ef-4cca-ae72-9f20f5975332"},"data":[{"interval":"2018-10-01T01:00:00.000Z/2018-10-07T01:00:00.000Z","metrics":[{"metric":"tSystemPresence","qualifier":"AWAY","stats":{"sum":949}},{"metric":"tSystemPresence","qualifier":"MEAL","stats":{"sum":2409}},{"metric":"tSystemPresence","qualifier":"MEETING","stats":{"sum":31909}},{"metric":"tSystemPresence","qualifier":"AVAILABLE","stats":{"sum":216862072}},{"metric":"tSystemPresence","qualifier":"OFFLINE","stats":{"sum":301492112}},{"metric":"tSystemPresence","qualifier":"TRAINING","stats":{"sum":7885}},{"metric":"tSystemPresence","qualifier":"BUSY","stats":{"sum":1839}},{"metric":"tSystemPresence","qualifier":"BREAK","stats":{"sum":825}}]}]}]}';

        String[] actuals = new String[] {};
        for (MyParser.Results r : MyParser.parse(jsonString).results) {
            MyParser.Group_Z g = r.group_Z;
            // Each d seems to represent a user
            for (MyParser.Data d : r.data) {
                // Each d seems to represent an interval
                for (MyParser.Metrics m : d.metrics) {
                    // Each m seems to repreent a metric
                    actuals.add('\n' + g.userId + ' ---- ' + d.interval + ' ---- ' + m.metric + ' ---- ' + m.stats.sum);
                }
            }
        }

        // This will always fail, but the test result shows the parsed values 
        String[] expecteds = new String[] {};
        System.assertEquals(expecteds, actuals);
    }
}
5
  • Im using JSON2Apex but got return null.. USER_DEBUG [106]|DEBUG|JSON ==>JSON2Apex:[filter=null, groupBy=null, interval=null, metrics=null, timeZone=null] Commented Oct 21, 2018 at 7:03
  • how to use this auto generated class from JSON2Apex btw, do you have some reference? Commented Oct 21, 2018 at 7:06
  • @AriefGunawanTjiptorahardja See the PPS or an example.
    – Keith C
    Commented Oct 21, 2018 at 12:54
  • Thanks a lot Keith! I appreciate your effort.. now I just need to loop the arrays Commented Oct 21, 2018 at 13:42
  • @AriefGunawanTjiptorahardja No problem. Good luck with getting the solution fleshed out.
    – Keith C
    Commented Oct 21, 2018 at 13:54
0

I can't post the code (yet), but I've found using untyped deserializing to be too-easy.

But instead of just paring it into a map, we wrap a class around the map that has all the usual map methods and:

getString(key) getString(key, valueIfNull) getDecimal(key) getDecimal(key, scale) getDecimal(key, scale, valueIfNull) getDateTime(...) getDate(...) getList(...) getMap(...) etc. etc.

you get the idea.

Recently we've added the ability to use key paths, like:

getString('parent/child/grandchild') to avoid callers from having to cascade gets() and make the code simpler.

My goal is always to make code as simple as possible. Using paths to get what the caller wants make its purpose easier to read then having to read-through the navigation.

Including the 'valueIfNull' parameter eliminates code like:

if (aMap.getString('aKey) == null) then someValue = valueIfNull else someValue = aMap.getString('aKey);

Or some similar code.

You must log in to answer this question.

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