How to reinitialise StaticJsonDocument from json string

Hi,

Im using a 'StaticJsonDocument' to hold config Key/Values for my configuration. So, I am storing ssid/password etc . This then gets written to the EEPROM for storage, however, if the ssid/password gets changed for some reason, I need to get the user to add replacement ssid/password from the web which is likely in json if the logon fails.

I tried to use deseralize(jsonDoc,jsonString), but that fails in that it does not seem to replace the values.

There is probably a simple solution but I dont currently see what it is, if someone has come across this, please post a proposed solutiuon.

Thank you.

There is a clear() method if you want to empty the doc but note the point

If you use the library as intended (see the examples and the book), you don’t need to call this function.

If you want to replace a value - just write in the doc


doc["pwd"] = “secret”;

Hi Jackson,

Thank you for your reply.

I am aware of the clear method, but I didn't want to have to individually set the values. What I wanted to be able to do is to deserialize an incoming json string and set the values in the existing document.

So, jsonDoc ( a StaticJsonDocument ) is a private member in a Config class. Which I gave empty placeholder values at Construction.

The values are then read read from either the EEPROM or sent via a web page, and the hope was that I could initialise all those members with a one line deserializeJson( jsonDoc, theJsonString).

This does not fail in that it does not throw an error, however, when the individual members of the jsonDoc are called via accessor functions, they are still blank. This I find a little odd, its almost as if it has created a jsonObject, but failed to connect it to the existing document.

clear did not help. I think I am going to have to rethink the whole approach.

Regards G

Maybe the ArduinoJson Assistant would be of help. It will write the Serialize and Deserialize code for you.

Does the incoming message include all the attributes (ie is the same structure as what you have in EEPROM)?

Hi Jackson,

Thanks for your reply.

The answer is exactly the same structure as is in the original, only the contents change, and that change is minimal, so by default ssid would be {"ssid":"Unspecified","password":Unspecified"} and when entered via the web or extracting from stored values in EEPROM would be {"ssid":"YourSSIDName","password":YourPassword"}.

Regards 'G'

Hi John,

Thanks for your reply.

I was not aware of this, so I will take a look and see if that offers some solice. :slight_smile:

Regards 'G'

Say you receive the new doc in updatedDoc and you have the other config in currentDoc

what prevents you from doing this?

currentDoc["ssid"] = updatedDoc["ssid"];
currentDoc["password"] = updatedDoc["password"];

have you looked at this example : ArduinoJson/JsonConfigFile.ino at 6.x · bblanchon/ArduinoJson · GitHub?

Hi Jackson,

I had not seen that example, but I see what you are saying. It may be worth trying, however, what I read about the Static container was that it cannot release memory. If this is true, than continuing to uses new JsonDocuments especially in a process which may iterate many times could possibly each up a lot of precious memory.

I guess I need to do some more reading, or perhaps completely rethink the use of Json and parse a response body token separated by pipes or something rare, or from EEPROM.

However, this all seems like it should be easy to do tbh, and either I am not understanding the right way to use the JsonDocument, or it has limitations that make it unsuitable for repeated used in a situation like this. Perhaps its a bit of both, usually understanding the problem better is usually the best way to choose either a solution using to what you are using, or rethink it.

I'll give it a try - Thanks.

it does not release it but it does not add to it either. The size is constant. So it makes sense to keep the preferences in a static document.

The JSON you get from the web could be a dynamic one, allocated only when you get the data and once assigned to the static one, then you get rid of it

Sure, ok, but lets say each time a user tries but fails to get the password or ssid correct when trying to log on, you use a method which creates a new temporary jsonDocument, you then use the members and transfer them across ( copy actually ) to the one which is a private member of the Config class of which it is a member. Each time you do think , do you not create a new and additional storage?

well it depends how you code it

You have code written to get the SSID and PWD from a web page as a JSON doc I assume

The JSON doc can either be a globally allocated doc or locally allocated.

if it's a global one, then no further allocation is done. You receive in one, transfer (copy) into the preferences and you are done;

If you allocate it locally dynamically, then get rid of it before exiting the function (depending on how you do it, getting out of scope will get rid of it).

You will sure allocate and deallocate but if there is no bug in the code, that won't be an issue (as long as there is enough RAM available for the allocation).

I'll try it, thanks for your help.

Hi Again,

It turned out that you were correct and that using a temporary document was the solution. So thanks for that. However, it seems to me that deserialize(doc, string), should if the construction of the json is the same and the contents fit, the allocation should be able to simply copy the values across for you.

In any case, its working now, and I am much happier to have a solution. Next time, I am not going to use this and I'm going to look for a more versatile approach. Shame really, this would otherwise be quite a slick way to do it.

If anyone reading this thinks, it still can be done by some wizard magic, I would be pleased to learn how.

Thank you Jackson, and other respondents.