How to parse JSON data from HTTP GET request using Arduino Mega 2560

Here is the response data from the GET request:

{\"success\":true,\"roast\":[{\"_id\":\"575750d1702890616a04e836\",\"name\":\"French Roast\",\"roastType\":\"Dark\",\"beanType\":\"Peruvian\",\"creatorID\":\"ebaytan\",\"RoastingData\":\"(0,340,45)\",\"rating\":0,\"__v\":0}]}

The quotes were manually escaped. Unsure if this is necessary depending on the library used.

How would I for example get the value of "success" or "roast"?

I would use a library

I'm actually using that Arduino JSON library but I am not getting any output after parsing.

Here is how I have it set up right now:

The variable "result" is the JSON string you see above.

StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(result);
const char* testSuccess = root["roast"];
Serial.println(testSuccess);

Heres a link to the JSON data itself: http://ec2-54-174-178-132.compute-1.amazonaws.com:9000/api/roast/French%20Roast

is result a char * ?

can you add the following code

Serial.println(result);
JsonObject& root = jsonBuffer.parseObject(result);

if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
} else {
        const char* testSuccess = root["roast"];
         Serial.println(testSuccess);
}

and share what you see in the console??

I checked your Json payload and it is well formed and has less than 200 bytes - so it's probably in the parsing unless you added the escaping \ character for the quotes. (in which case you went probably beyond 200 chars) and I don't think it's needed

{
   "success":true,
   "roast":[
       {
            "_id":"575750d1702890616a04e836",
            "name":"French Roast",
            "roastType":"Dark",
            "beanType":"Peruvian",
            "creatorID":"ebaytan",
            "RoastingData":"(0,340,45)",
            "rating":0,
            "__v":0
       }
   ]
}

"result" is declared as a String.

Here is the output from the monitor:

{\"success\":true,\"roast\":[{\"_id\":\"575750d1702890616a04e836\",\"name\":\"French Roast\",\"roastType\":\"Dark\",\"beanType\":\"Peruvian\",\"creatorID\":\"ebaytan\",\"RoastingData\":\"(0,340,45)\",\"rating\":0,\"__v\":0}]}
parseObject() failed

"result" is declared as a String.

a String with a capital S is not a suitable char * or char array.

use const char * msg = result.c_str(); and pass msg to the parser (might work did not try but I don't think the parser needs to mess with the string, so a const char * should work)

Also you have escaped the \ " and now you have 226 chars while your Json buffer can only hold 200

I don't think you need to escape them

I added:

const char* msg = result.c_str();
Serial.println(msg);
JsonObject& root = jsonBuffer.parseObject(msg);

and also increased the buffer to 400

The output is the same on the serial monitor:

{\"success\":true,\"roast\":[{\"_id\":\"575750d1702890616a04e836\",\"name\":\"French Roast\",\"roastType\":\"Dark\",\"beanType\":\"Peruvian\",\"creatorID\":\"ebaytan\",\"RoastingData\":\"(0,340,45)\",\"rating\":0,\"__v\":0}]}
parseObject() failed

try getting rid of the \

they should not be in the actual string. they are needed if you do something like

char myJson[] = "{\"success\":true,\"roast\":[{\"_id\":\"575750d1702890616a04e836\",\"name\":\"French Roast\",\"roastType\":\"Dark\",\"beanType\":\"Peruvian\",\"creatorID\":\"ebaytan\",\"RoastingData\":\"(0,340,45)\",\"rating\":0,\"__v\":0}]}"

because otherwise the parser will bark at you but if you build that dynamically and it's returned from a web page, then the chars in memory will just be fine

and just for testing, try passing a locally defined Json to the parser and see if that works

JsonObject& root = jsonBuffer.parseObject("{\"success\":true,\"roast\":[{\"_id\":\"575750d1702890616a04e836\",\"name\":\"French Roast\",\"roastType\":\"Dark\",\"beanType\":\"Peruvian\",\"creatorID\":\"ebaytan\",\"RoastingData\":\"(0,340,45)\",\"rating\":0,\"__v\":0}]}");
if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
} else {
        const char* testSuccess = root["roast"];
         Serial.println(testSuccess);
}

I tried it without \ " and parseObject() failed.

Here's the code I have:

Adafruit_CC3000_Client lightRoastClient = cc3000.connectTCP(ip, 80);
    char c;
    String result = "";

    StaticJsonBuffer<400> jsonBuffer;
  
  // GET:
  if (lightRoastClient.connected()) {
    lightRoastClient.fastrprint(F("GET "));
    lightRoastClient.fastrprint(lightRoastWEBPAGE);
    lightRoastClient.fastrprint(F(" HTTP/1.1\r\n"));
    lightRoastClient.fastrprint(F("Host: ")); 
    lightRoastClient.fastrprint(WEBSITE);
    lightRoastClient.fastrprint(F("\r\n"));
    lightRoastClient.fastrprint(F("\r\n"));
    lightRoastClient.println();
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }

  /* Read data until either the connection is closed, or the idle timeout is reached. */ 
  unsigned long lastRead = millis();
  while (lightRoastClient.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (lightRoastClient.available()) {
      c = lightRoastClient.read();
      
//      if (c == '"') {
//        result = result + '\\';
//      }
        result = result + c;

      if (result.endsWith("Connection: keep-alive")) {
        result = "";
      }
      lastRead = millis();
    }
  }

  const char* msg = result.c_str();
  Serial.println(msg);
  JsonObject& root = jsonBuffer.parseObject(msg);

  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  } else {
    const char* testSuccess = root["roast"];
    Serial.println(testSuccess);
  }

Sorry actually double checked the documentation and they say

As you can see parseObject() takes a char* as a parameter. Be careful, it's not a const char*, the memory must be writable. Indeed, the parser will modify the string in two cases:

to insert string endings (character \0),
to translate escaped characters (like \n or \t).

so don't do a

const char* msg = result.c_str();
Serial.println(msg);
JsonObject& root = jsonBuffer.parseObject(msg);

because then you pass a const char*

so do a

char msg[300];
strcpy(msg, result.c_str());
Serial.println(msg);
JsonObject& root = jsonBuffer.parseObject(msg);

that's for testing only because you are really eating up all your memory with this. in practice don't use the String with a capital C, build a string (char array) right away instead of doing result = result + c;

I made the changes and it now does not fail to parse. However, it does not print anything.

Here is the code:

  char msg[300];
  strcpy(msg, result.c_str());
  Serial.println(msg);
  JsonObject& root = jsonBuffer.parseObject(msg);

  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  } else {
    const char* testSuccess = root["roast"];
    Serial.println(testSuccess);
  }

Here's the output from the serial monitor:

{"success":true,"roast":[{"_id":"575750d1702890616a04e836","name":"French Roast","roastType":"Dark","beanType":"Peruvian","creatorID":"ebaytan","RoastingData":"(0,340,45)","rating":0,"__v":0}]}
root["roast"];

should be

   "roast":[
       {
            "_id":"575750d1702890616a04e836",
            "name":"French Roast",
            "roastType":"Dark",
            "beanType":"Peruvian",
            "creatorID":"ebaytan",
            "RoastingData":"(0,340,45)",
            "rating":0,
            "__v":0
       }
   ]

so it's an array with 1 object of 6 strings and 2 numbers. so I don't think you can print it that way, it's not a string that println can handle.

JsonArray& nestedArray = root["roast"]; will give you the pointer to that array and then you can extract individual values from it.

just for checking can you modify the code to read

  char msg[300];
  strcpy(msg, result.c_str());
  Serial.println(msg);
  JsonObject& root = jsonBuffer.parseObject(msg);

  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  } else {
    Serial.println("parseObject() SUCCESS");
      for (JsonObject::iterator it=root.begin(); it!=root.end(); ++it)  {
           Serial.println(it->key);
           Serial.println(it->value.asString()); 
       }
  }

I appreciate the help J-M-L.

My friend and I were able to figure it out by using one of the examples for the library and just modifying the JSON input and different variables that were being grabbed.

Thanks for the fast responses and willingness to help!

pleasure - good to know it's solved