Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Munque
Posts: 25
Joined: Mon Feb 10, 2020 11:38 pm

Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby Munque » Mon May 11, 2020 3:59 am

I'm using a WiFiClient to download an array (JSON.stringify(["Test1", "Test2"]) from a Node JS server and have it converted on the C++ side into an ArduinoJson array.

The problem: The array ends up empty.

Code: Select all

void GetListFromServerUsingArduinoJson(){
	WiFiClient client;
	//Skipping some code here: client.connect(), make request, receive response, parse out headers etc.
	//So we're continuing with the response body... a string representation of a JSON Array:
	String arrayStr;
	char currentChar;
	while(client.available()){
		currentChar=client.read();
		arrayStr.concat(currentChar);
	}
	Serial.println(arrayStr); // All working to this point. Result is "[\"Test1\",\"Test2\"]";
	StaticJsonDocument<50> arrayObj;
	DeserializationError Err=deserializeJson(arrayObj, arrayStr);
	if(Err){
		Serial.println("Array Test Failed"); //No error, so far so good.
	}else{
		int arrayLength=arrayObj.size();
		Serial.println(arrayLength); //Problem here: shows 0.  arrayObj is indeed empty
	}
}
Note: Replacing the 'deserializeJson' step above with the following works fine:
DeserializationError Err=deserializeJson(arrayObj, "[\"Test1\",\"Test2\"]");

Is the problem that that arrayStr is not a string literal or const String?
but if that's the case I'm not sure how to resolve the above issue.

User avatar
fasani
Posts: 195
Joined: Wed Jan 30, 2019 12:00 pm
Location: Barcelona
Contact:

Re: Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby fasani » Mon May 11, 2020 10:24 am

I'm at the moment on a completely different topic but I have a very good suggestion for you:
Stop using Strings and try to do the things using chars[]

I had a lot of problems using Strings and learned the hard way to do things differently. One way is using strlcat, as an example, you can check here how an HTTP request is built:
https://github.com/martinberlin/eink-ca ... n.cpp#L428

On another topic: You don't need to use String.concat() like this. A string can be also concatenated simply like

myString = myString + "my new String";
epdiy collaborator | http://fasani.de Fan of Espressif MCUs and electronic design

Munque
Posts: 25
Joined: Mon Feb 10, 2020 11:38 pm

Re: Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby Munque » Mon May 11, 2020 1:05 pm

myString = myString + "my new String";
I'd read somewhere that a) Don't use strings, and b) But if you do, don't use myString + "my new String", but the concat() method.


completely different topic / Stop using Strings and try to do the things using chars[]
Actually per this question that's right on topic. I'm aware of the 'Stop using Strings' rule in C++ but so far haven't succeeded at making the transition. At one point I sat down and devoted hours to just figuring out how to do that and but didn't succeed. There's always some procedure that defies the effort. Perhaps your links will finally set me on the right path.

Question: Why the use of strlcat instead of strncat. The strlcat link has a big 'non-standard' warning and some other notes suggesting to go with strncat.

Thanks again.

Munque
Posts: 25
Joined: Mon Feb 10, 2020 11:38 pm

Re: Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby Munque » Mon May 11, 2020 1:29 pm

In attempting to test (and learn more about how to work with) char arrays I tried the following addition to the original code:

Code: Select all

Serial.println(arrayStr); // All working to this point. Result is "[\"Test1\",\"Test2\"]";
//char array test
int arrayLgth=arrayStr.length();
char arrayChar[arrayLgth + 1];
strcpy(arrayChar, arrayStr.c_str()); 
Serial.println(arrayChar); // All working to this point. Result is "[\"Test1\",\"Test2\"]";
//----
StaticJsonDocument<50> arrayObj;
DeserializationError Err=deserializeJson(arrayObj, arrayChar); //Result arrayObj still ends up empty.

Munque
Posts: 25
Joined: Mon Feb 10, 2020 11:38 pm

Re: Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby Munque » Mon May 11, 2020 3:15 pm

Problem resolved:

The issue was actually on the Node JS side where the array was accidentally JSON.stringify'd twice.
So for the most part this is an issue unrelated to C++ Strings and char arrays.

The significant relevance to C++ is this...
Beginning on the JS Side:
JSON.stringy(); //gives the string: ["Test", "Test2"]
JSON.stringify(JSON.stringify(["Test", "Test2"])); //i.e. a mistake that results in a string "[\"Test\", \"Test2\"]]"

Over on the C++ side which picked up the JS error
Serial.println(arrayString); //showed "[\"Test1\",\"Test2\"]" which I described as "all good up to this point". False. Serial.print would have shown the array without any escapes: ["Test", "Test2"] had it been all done correctly.

The good news is it only took an enormous amount of wasted time to figure this out.

User avatar
fasani
Posts: 195
Joined: Wed Jan 30, 2019 12:00 pm
Location: Barcelona
Contact:

Re: Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby fasani » Tue May 12, 2020 6:09 am

>Question: Why the use of strlcat instead of strncat. The strlcat link has a big 'non-standard' warning and some other notes suggesting to go with strncat.

I'm not really so versed in C++ to answer this question. But my recommendation is to follow examples that don't use strings.

It boils down to this point for me. In C++ and doing embeddded software this is stored in the chips memory, doing char[] you can control it in a good level, using the String class you never really know what's happening at the other end.
For example in this FIrmware CALE I was having ugly bugs that only from time to time (like 1 each 10 times) it will parse wrongly the URL because I was heavy dependant of Strings. Updating that to chars and concatenation using strlcat solved it.

I really don't care about the standard warnings as long as the code is stable and does what is supposed to do.
epdiy collaborator | http://fasani.de Fan of Espressif MCUs and electronic design

Munque
Posts: 25
Joined: Mon Feb 10, 2020 11:38 pm

Re: Unable to convert a JS JSON.stringify'd array to a C++ ArduinoJson equivalent -- empty array

Postby Munque » Tue May 12, 2020 1:52 pm

> my recommendation is to follow examples that don't use strings.

Agreed. It's just taking a while to figure out how convert from a String mindset to the char array approach. There are a variety procedures I can execute fluently with Strings that require extra steps the land of char, and I'm not yet 100% familiar with them. Slow going.


> I was having ugly bugs that only from time to time (like 1 each 10 times) it will parse wrongly the URL

For the moment the I'm operating under the assumption that Strings declared within, used, and disposed of within the confines of a function are relatively safe. I have a number of elaborate routines making extensive use of Strings running in Esp32 and Esp8266 that perform without any problems, continuously for about a year. I'm not promoting the continued use of Strings over char, just to say I haven't been having problems to date, which affords me some leeway as I try to iron out all the challenges of converting to char arrays.

I wonder if the wrongly-parsed URL issues you were having were the result of declaring global Strings and then repeatedly changing them. I believe (and am hardly certain) that this is the core danger of using strings.

Who is online

Users browsing this forum: lbernstone and 153 guests