Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Json util method returning invalid result

i need help understanding what i am missing in the logic for my json utility method that is returning an array of elements. I am not that familiar with rapidjson and can only add debug prints in my code. So my json.h file looks like below

template <>
std::vector<std::string> fetchStringArray<std::vector<std::string>>(const rapidjson::Value& value){
    std::cout<<"Enter\n";
    std::vector<std::string> elements;
    if (!value.IsArray()) {
        std::cout<<"Early Exit\n";
        return elements;
    }

    for (auto& item : value.GetArray()) {
        if (item.IsString()) {
            elements.push_back(item.GetString());
        }
    }
    std::cout<<"Success\n";
    return elements;
}

template <>
vector<string> fetchStringArray<vector<string>>(const string& jsonString, const string& key){
       std::cout<<"2\n";
       rapidjson::Document document;
       std::cout <<"JsonString "<<jsonString<<"\n";
       document.Parse(jsonString);
       if(document.HasMember("key")){
           std::cout <<"key found "<<"\n";
       }
    
       if (document.HasParseError()) {
           return std::vector<string>();
       }
    
     return fetchStringArray<vector<string>>(document);
}

template <class CollectionT>  
CollectionT fetchStringArray(const string& jsonString, const string& key) {
     std::cout<<"4\n";
     auto values = fetchStringArray<std::vector<std::string>>(jsonString, key);
     return CollectionT{values.begin(), values.end()};
}

The jsontests.cpp test file looks like below

/// test fixture.
class JsonTests : public ::testing::Test {};

/**
 * Test fetchStringArray
 */
TEST_F(JsonTests, test_fetchStringArray) {
    char key[] = "key";
    auto entries = fetchStringArray<std::set<std::string>>(R"({"key":["ONE","TWO"]})", key);
    ASSERT_EQ(entries.size(), 2u);
    EXPECT_NE(entries.find("ONE"), entries.end());
    EXPECT_NE(entries.find("TWO"), entries.end());
}

But when i run the test i get thE FOLLOWING OUTPUT

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

4
2
JsonString {"key":["ONE","TWO"]}
key found 
Enter
Early Exit
/Foo/test/JsonTestS.cpp:23: Failure
      Expected: entries.size()
      Which is: 0
To be equal to: 2u
      Which is: 2
[  FAILED  ] JsonTests.test_fetchStringArray (0 ms)
    

Any help or pointers will be greatly appreciated.

>Solution :

To fix the issue, you need to extract the rapidjson::Value associated with the key from the document and pass that to the function fetchStringArray.

Here’s how you can modify your code:

template <>
std::vector<std::string> fetchStringArray<std::vector<std::string>>(const rapidjson::Value& value) {
    std::cout << "Enter\n";
    std::vector<std::string> elements;
    if (!value.IsArray()) {
        std::cout << "Early Exit\n";
        return elements;
    }

    for (auto& item : value.GetArray()) {
        if (item.IsString()) {
            elements.push_back(item.GetString());
        }
    }
    std::cout << "Success\n";
    return elements;
}

template <>
std::vector<std::string> fetchStringArray<std::vector<std::string>>(const std::string& jsonString, const std::string& key) {
    std::cout << "2\n";
    rapidjson::Document document;
    std::cout << "JsonString " << jsonString << "\n";
    document.Parse(jsonString.c_str());

    if (document.HasParseError()) {
        return std::vector<std::string>();
    }

    if (document.HasMember(key.c_str())) {  // Use c_str() to convert std::string to const char*
        std::cout << "key found\n";
        const rapidjson::Value& value = document[key.c_str()];
        return fetchStringArray<std::vector<std::string>>(value);  // Pass the value associated with the key
    }

    return std::vector<std::string>();  // If the key is not found, return an empty vector
}

template <class CollectionT>
CollectionT fetchStringArray(const std::string& jsonString, const std::string& key) {
    std::cout << "4\n";
    auto values = fetchStringArray<std::vector<std::string>>(jsonString, key);
    return CollectionT{values.begin(), values.end()};
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading