Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return JSON as reference #1631

Closed
nyckmaia opened this issue Jun 10, 2019 · 5 comments
Closed

Return JSON as reference #1631

nyckmaia opened this issue Jun 10, 2019 · 5 comments

Comments

@nyckmaia
Copy link

nyckmaia commented Jun 10, 2019

Hi, I would like to get a reference to a JSON object that is a private member of my Application Class

// for convenience
using json = nlohmann::json;

---- My class ------

class APPLICATION
{
private:
    json _file;

public:
    json& get_file(void) { 
        return _file; 
    }

    void save_file(void) { 
        std::ofstream o("out.json");
	o << std::setw(4) << _file << std::endl;
    }
}

------ My Main ----------

// Create a new instance:
APPLICATION app;

// Get the internal private member reference:
json j = app.get_file();

// Add/Modify the internal JSON variable:
j["new_field_added"] = "New field"

//  Save the modified JSON to a output file:
app.save_file();

I got no errors in compile time, but the new modifications that I should do in the Main function do not be apply in the original private member (_file).
That is, the JSON private member remains unchanged.

How can I do it?

@nickaein
Copy link
Contributor

You probably need an & in the second line otherwise it will be copy-constructed:

// Get the internal private member reference:
json& j = app.get_file();

@nyckmaia
Copy link
Author

nyckmaia commented Jun 11, 2019

Thank you!

I added the "&" and got it working now!

My last ImGui problem is in this code:

// Get the internal private member reference:
json& j = app.get_file();

// Create a new JSON object:
json n;

// Fill the new JSON object with dummy data:
n["new1"] = "new field";
n["new2"].push_back("item 1");
n["new2"].push_back("item 2");
n["new2"].push_back("item 3");

// Insert the new JSON object into the private member JSON object:
// **IMPORTANT: This private JSON alreay have the "pecas" array inside it.**
j["pecas"].push_back(n);

// Save the modified JSON to a output file:
app.save_file("");

I got no errors in compilation time, but when I ran it in Visual Studio 2019, it goes to json.hpp file, line 1562 (default switch option):
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));

Here is the exception message:

Unhandled exception at 0x00007FFB368B9129 in rotortest_app.exe: Microsoft C++ exception: nlohmann::detail::type_error at memory location 0x00000070265EED78. occurred

Here is the json.hpp function context:

void from_json(const BasicJsonType& j, ArithmeticType& val)
{
    switch (static_cast<value_t>(j))
    {
        case value_t::number_unsigned:
        {
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
            break;
        }
        case value_t::number_integer:
        {
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
            break;
        }
        case value_t::number_float:
        {
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
            break;
        }
        case value_t::boolean:
        {
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
            break;
        }

        default:
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
    }
}

How can I do the "push_back" operation to add the new JSON object into the JSON private member?

Thanks!

@nickaein
Copy link
Contributor

nickaein commented Jun 11, 2019

// Fill the new JSON object with dummy data:
n["new1"] = "new field";
n["new2"].push_back("item 1");
n["new2"].push_back("item 2");
...

I'm not sure if it is necessary in this case, but it is always a good practice to be explicit in object construction. So, you might use json::array() when constructing an array:

// Fill the new JSON object with dummy data:
n["new1"] = "new field";
n["new2"] = json::array();
n["new2"].push_back("item 1");
n["new2"].push_back("item 2");
...

// Insert the new JSON object into the private member JSON object:
// This private JSON alreay have the "pecas" array inside it.
j["pecas"].push_back(n);

Does that mean j["pecas"] is an array of JSON objects and you are appending n to them? Because otherwise, an exception will be thrown.

Also, can you put try/catch block(s) around your code to find out which line is throwing the exception? If you are on Visual Studio, you can check the trace trace too to find out which line in your source code has lead to an exception.

@nyckmaia
Copy link
Author

Thank you Nickaein, and sorry about that...

Following your directions I found that actually my error is in the GLFW loop when its try to load the "new fields" (json n) that are not supported inside my C++ GUI code yet.

By the way, this JSON library is really amazing!

Thank you!

@nickaein
Copy link
Contributor

No problem!

Yes, it is indeed an amazing library, thanks to all people who has contributed and users who reported their issues :-)

If you don't need further assistant on this particular issue you can close it. You are welcome to open a separate issue for future questions/requests/bug reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants