1

I have the following string as a response from a HttpResponse variable using its getBody() function:

{"data":{"chat":[{"speaker":"Speaker 0","startTime":"0.16","message":"for technology positions so that you know your parties four digit extension you may dial it at anytime for a dial by name directory press pound"},{"speaker":"Speaker 1","startTime":"12.04","message":"from member of your team"}],"wordTime":{"for":[{"from":0.16,"to":0.32},{"from":7.93,"to":8.02}],"technology":[{"from":0.32,"to":1.02}],"positions":[{"from":1.11,"to":1.59}],"so":[{"from":1.59,"to":1.7}],"that":[{"from":3.36,"to":3.49}],"you":[{"from":3.49,"to":3.58},{"from":5.59,"to":5.68}],"know":[{"from":3.58,"to":3.73}],"your":[{"from":3.73,"to":3.88},{"from":12.82,"to":13.05}],"parties":[{"from":3.88,"to":4.22}],"four":[{"from":4.35,"to":4.55}],"digit":[{"from":4.55,"to":4.86}],"extension":[{"from":4.86,"to":5.44}],"may":[{"from":5.68,"to":5.77}],"dial":[{"from":5.77,"to":6.15},{"from":8.07,"to":8.38}],"it":[{"from":6.15,"to":6.25}],"at":[{"from":6.25,"to":6.38}],"anytime":[{"from":6.38,"to":6.91}],"a":[{"from":8.02,"to":8.07}],"by":[{"from":8.38,"to":8.51}],"name":[{"from":8.51,"to":8.76}],"directory":[{"from":8.76,"to":9.34}],"press":[{"from":9.61,"to":10.02}],"pound":[{"from":10.09,"to":10.47}],"from":[{"from":12.04,"to":12.2}],"member":[{"from":12.2,"to":12.5}],"of":[{"from":12.5,"to":12.59}],"team":[{"from":13.09,"to":13.42}]},"audioDuration":13.608,"convertedAudioSize":13869,"status":1}}

I converted the string into a Map<String,Object> using the following code:

Map<String,Object> mappedResponse = (Map<String,Object>)JSON.deserializeUntyped(response.getBody());

I obtained the field data inside an Object value:

Object value = (Object) mappedResponse.get('data');

And the problem starts when I want to get the wordTime element inside the Object the String has been shortened from:

"wordTime":{"for":[{"from":0.16,"to":0.32},{"from":7.93,"to":8.02}],"technology":[{"from":0.32,"to":1.02}],"positions":[{"from":1.11,"to":1.59}],"so":[{"from":1.59,"to":1.7}],"that":[{"from":3.36,"to":3.49}],"you":[{"from":3.49,"to":3.58},{"from":5.59,"to":5.68}],"know":[{"from":3.58,"to":3.73}],"your":[{"from":3.73,"to":3.88},{"from":12.82,"to":13.05}],"parties":[{"from":3.88,"to":4.22}],"four":[{"from":4.35,"to":4.55}],"digit":[{"from":4.55,"to":4.86}],"extension":[{"from":4.86,"to":5.44}],"may":[{"from":5.68,"to":5.77}],"dial":[{"from":5.77,"to":6.15},{"from":8.07,"to":8.38}],"it":[{"from":6.15,"to":6.25}],"at":[{"from":6.25,"to":6.38}],"anytime":[{"from":6.38,"to":6.91}],"a":[{"from":8.02,"to":8.07}],"by":[{"from":8.38,"to":8.51}],"name":[{"from":8.51,"to":8.76}],"directory":[{"from":8.76,"to":9.34}],"press":[{"from":9.61,"to":10.02}],"pound":[{"from":10.09,"to":10.47}],"from":[{"from":12.04,"to":12.2}],"member":[{"from":12.2,"to":12.5}],"of":[{"from":12.5,"to":12.59}],"team":[{"from":13.09,"to":13.42}]}

To

wordTime={a=({from=8.02, to=8.07}), anytime=({from=6.38, to=6.91}), at=({from=6.25, to=6.38}), by=({from=8.38, to=8.51}), dial=({from=5.77, to=6.15}, {from=8.07, to=8.38}), digit=({from=4.55, to=4.86}), directory=({from=8.76, to=9.34}), extension=({from=4.86, to=5.44}), for=({from=0.16, to=0.32}, {from=7.93, to=8.02}), four=({from=4.35, to=4.55}), ...}]

And when I receive the value of that object on visualForce I'm getting the shortened string.

How can I avoid this situation?

Thanks in advance.

UPDATE:

This is the code of the function that gets the response:

public static RqaCallLogObject getCallLogSerializer(HttpResponse response){
        RqaCallLogObject callLog = new RqaCallLogObject();
        if(response.getStatusCode() == RqaConstants.SUCCESS){
            Map<String,Object> mappedResponse = (Map<String,Object>)JSON.deserializeUntyped(response.getBody());
            Object value = (Object) mappedResponse.get('data');
            Map<String,Object> mappedValue = (Map<String,Object>)value;

            System.debug('mappedResponse: ' + mappedResponse);
            System.debug('response body: ' + response.getBody());

            callLog.audioDuration = Decimal.valueOf(String.valueOf(mappedValue.get('audioDuration')));
            callLog.convertedAudioSize = Integer.valueOf(String.valueOf(mappedValue.get('convertedAudioSize')));
            callLog.wordTime = mappedValue.get('wordTime');
            callLog.chat = String.valueOf(mappedValue.get('chat'));
            callLog.status = Integer.valueOf(String.valueOf(mappedValue.get('status')));
            callLog.message = '';
        }
        return callLog;
    }

The visualForce code that I'm using is a javascript remoting function that receives as a result the callLog variable, so I guess it's not too important here since the issue is happening in Apex

2
  • Can you please show the apex and visualforce code your're using.
    – Eduard
    Jul 11, 2018 at 16:35
  • I added my Apex function @Eduard
    – Manu
    Jul 11, 2018 at 16:49

1 Answer 1

3

The problem is not that your string is being cut off, it's that you're processing the data incorrectly. A System.debug statement automatically trims large objects so they don't consume the entire log file. The problem is that you're messing up the JSON data with how you're parsing the JSON. You need to fix your RqaCallLogObject so it reflects the proper data structure, or just return the raw data from the callout and JSON-parse on the client-side.


Parsing On Client

public static String getCallLogSerializer(HttpResponse response){
  return response.getBody();
}

function remoteActionCallback(response, event) {
  var results = JSON.parse(response);
  ...

Parsing In Apex Code

class ChatData {
  String speaker;
  String startTime;
  String message;
}
class MainData {
  Decimal audioDuration;
  List<ChatData> chat;
  Long convertedAudioSize;
  Integer status;
  Map<String, List<Map<String, Decimal>>> wordTime;
}
class DataWrapper {
  MainData data;
}

Which you can then parse explicitly:

public static MainData getCallLogSerializer(HttpResponse response);
  // ... other checks here
  DataWrapper result = (DataWrapper)JSON.deserialize(response.getBody(), DataWrapper.class);
  return result.data;
}
3
  • I did't have think of getting the info with this perspective. By the way, this worked like a charm, thanks a lot.
    – Manu
    Jul 11, 2018 at 17:33
  • 2
    @ManuelVasquezPimentel You're welcome. This JSON was actually a bit tricky because of the wordTime thing, but once you understand the theory behind how I did it, you shouldn't have any trouble doing this in the future. Basically, you can always parse a JSON object as a Map<String, SomeType>, you just need to figure out what SomeType needs to be.
    – sfdcfox
    Jul 11, 2018 at 17:38
  • You're right sir @sfdcfox, I've been checking some other examples and considering the appliance of my own ways based on the examples that I applied previously. But this is a different approach that's useful to apply and also to learn.
    – Manu
    Jul 11, 2018 at 17:41

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.