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

Value function return empty object even if it exist #2086

Closed
xamix opened this issue May 4, 2020 · 5 comments · Fixed by #2104
Closed

Value function return empty object even if it exist #2086

xamix opened this issue May 4, 2020 · 5 comments · Fixed by #2104
Labels
confirmed kind: question state: please discuss please discuss the issue or vote for your favorite option

Comments

@xamix
Copy link

xamix commented May 4, 2020

  • Describe what you want to achieve.
    I need to get a default empty object in case an item do not exist in the specified json.

  • Describe what you tried.
    Using the function value.

  • Describe which system (OS, compiler) you are using.
    GCC 9 on Ubuntu x64.

  • Describe which version of the library you are using (release version, develop branch).
    I use develop branch.

Here is a simple example to demonstrate my question:

#include <iostream>

#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main()
{
    json j = {
        {"what", "i'm here"}
    };

    json k = j.value("what", json::value_t::object);

    std::cout << "j:" << j.dump(4) << std::endl;
    std::cout << "k:" << k.dump(4) << std::endl;
    return 0;
}

This output k as empty even if the item exist:

j:{
    "what": "i'm here"
}
k:""

However it works (k is filled with the good value i'm here) if I change the call of value with one of the following:

json k = j.value<json>("what", json::value_t::object);
or
json k = j.value("what", json({}));

Is this the expected behavior?

@nlohmann
Copy link
Owner

nlohmann commented May 4, 2020

This seems like a bug. A quick fix would be to pass json::object() instead of json::value_t::object as parameter.

@xamix
Copy link
Author

xamix commented May 5, 2020

I confirm that it works with json::object().

Also it seem to fail if I want a null object by using:

json k = j.value("what", json::value_t::null);

@dota17
Copy link
Contributor

dota17 commented May 9, 2020

json::value_t::object shold not be passed directly into value() unless it is converted to json type, like value<json>("what", json::value_t::object). Obviously, this type of parameter is not handled correctly in the code, at least, it should remind the caller type error.

Or we should explicitly specify the parameter as the object type:
template<class ValueType, typename std::enable_if<
std::is_convertible<basic_json_t object_t, ValueType>::value, int>::type = 0>
ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const

@nlohmann
Copy link
Owner

nlohmann commented May 9, 2020

It should be ok to pass json::value_t::object, because json(json::value_t::object) is valid code to create an empty object. I have not understood why the code above does not work as expected, though.

@nlohmann
Copy link
Owner

I had another look at this: The requirment for allowing code like

json k = j.value("what", json::value_t::object);

is that the type of the second argument, json::value_t, can be converted to basic_json, and indeed it can be via member function

constexpr operator value_t() const noexcept
{
    return m_type;
}

So we check the object j at key "what", find a JSON value of type string ("i'm here"). This is then converted to value_t when the value function returns. As the function above does this conversion by returning m_type, value returns json::value_t::string. This value is then used to initialize json k to an empty string.

I now tend to agree with @dota17 that passing value_t to value should be disallowed. Any thoughts on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed kind: question state: please discuss please discuss the issue or vote for your favorite option
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants