Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Can't convert QJsonValue to any type



  • I'm having a weird problem where I can't seem to convert a QJsonValue to any of the possible values.

    The piece of JSON data I'm trying to parse is this:

    }
        "payload":{
            "orders":[
                {
                    "last_update":"2018-08-28T16:09:01+00:00",
                    "platinum":11,
                    "creation_date":"2015-12-24T14:20:21+00:00",
                    "id":"567bff25cbfa8f06d7e8290b",
                    "platform":"pc",
                    "quantity":27,
                    "region":"en",
                    "order_type":"sell",
                    "visible":true
                },
                {
                    "last_update":"2018-08-29T14:38:35+00:00",
                    "platinum":75,
                    "creation_date":"2016-01-11T12:42:42+00:00",
                    "id":"5693a342cbfa8f263aeb7d02",
                    "platform":"pc",
                    "quantity":1,
                    "region":"en",
                    "order_type":"sell",
                    "visible":true
                },
                {
                    "last_update":"2018-08-18T11:03:56+00:00",
                    "platinum":35,
                    "creation_date":"2016-06-11T18:38:37+00:00",
                    "id":"575c5aadd3ffb658a3916831",
                    "platform":"pc",
                    "quantity":1,
                    "region":"en",
                    "order_type":"sell",
                    "visible":true
                }
    	]
        }
    }
    

    Like you can see, the "orders" value is an Array.

    But when I try to convert it into a QJsonArray, it gives me an array with a length of 0:

    // Converts each order in the JSON data into a C++ data structure and returns all of them in a QList.
    QList<WFMOrder> WFMOrder::fromFullJson(const QJsonDocument& json)
    {
        QList<WFMOrder> orders;
    
        QJsonValue value = json["payload"]["orders"];
        qDebug() << "isArray = " << value.isArray(); // This is false
        qDebug() << "isObject = " << value.isObject(); // This is false
        qDebug() << "isString = " << value.isString(); // This is false
        qDebug() << "isNull = " << value.isNull(); // This is false
        qDebug() << "isBool = " << value.isBool(); // This is false
        qDebug() << "isDouble = " << value.isDouble(); // This is false
        qDebug() << "Object count in orders: " << value.toArray().count(); // This is 0
        for (int i = 0; i < value.toArray().count(); i++) // This runs 0 times.
        {
            WFMOrder order(json, i);
            orders.append(order);
        }
    
        return orders; // The length of the returned QList is also 0
    }
    

    I'm a little confused, what am I doing wrong?


  • Lifetime Qt Champion

    Hi
    Are you sure that syntax works ?
    QJsonValue value = json["payload"]["orders"];
    since "payload": is object not array.
    Anyway i would try to call
    http://doc.qt.io/qt-5/qjsonvalue.html#isArray
    on value to see what it says.



  • @mrjj Calling isArray, isBool, isObject, isDouble, isString and isNull on value all returns false.
    I believe the syntax does work since I can do this value[0]["platinum"].toInt() which returns 11, and that matches what the JSON data has in the platinum field.


  • Lifetime Qt Champion

    @TheMushroom
    Ah sorry i missed u already called all the isX

    hmm if
    value[0]["platinum"].toInt()
    works then syntax is ok. ( didnt know. cool)
    but that implies that value is in fact an array
    but at same time value.isArray(); returns false?

    i wondering if u need to call
    QJsonValue::toArray()





  • @mrjj I tried value.toArray() as well, but it also produced an empty array.

    @VInay123 I can't seem to loop the QJsonObject like they do in the stackoverflow post, it gives me this error:
    non-const lvalue reference to type 'QJsonValueRef' cannot bind to a temporary of type 'QJsonValueRef'

    QJsonObject obj = json["payload"]["orders"].toObject();
    for (auto& order : obj) // non-const lvalue reference to type 'QJsonValueRef' cannot bind to a temporary of type 'QJsonValueRef'
    {
            
    }
    


  • @TheMushroom Which compiler are you using? I think in VS it must work.



  • @VInay123 I'm using the MinGW compiler.


  • Qt Champions 2019

    @TheMushroom said in Can't convert QJsonValue to any type:

    for (auto& order : obj)

    you're missing the const:
    --> for (const auto & order : obj)



  • @Christian-Ehrlicher That fixed the error but it doesn't loop at all. Added qDebug() << "Looped"; inside it, which didn't run a single time.


  • Qt Champions 2019

    Why not simply writing a small testcase?

    const QByteArray jsonBa = R"raw(
    {
      "payload":{
            "orders":[
                {
                    "last_update":"2018-08-28T16:09:01+00:00",
                    "platinum":11,
                    "creation_date":"2015-12-24T14:20:21+00:00",
                    "id":"567bff25cbfa8f06d7e8290b",
                    "platform":"pc",
                    "quantity":27,
                    "region":"en",
                    "order_type":"sell",
                    "visible":true
                },
                {
                    "last_update":"2018-08-29T14:38:35+00:00",
                    "platinum":75,
                    "creation_date":"2016-01-11T12:42:42+00:00",
                    "id":"5693a342cbfa8f263aeb7d02",
                    "platform":"pc",
                    "quantity":1,
                    "region":"en",
                    "order_type":"sell",
                    "visible":true
                },
                {
                    "last_update":"2018-08-18T11:03:56+00:00",
                    "platinum":35,
                    "creation_date":"2016-06-11T18:38:37+00:00",
                    "id":"575c5aadd3ffb658a3916831",
                    "platform":"pc",
                    "quantity":1,
                    "region":"en",
                    "order_type":"sell",
                    "visible":true
                }
    	]
      }
    })raw";
    
    QJsonParseError err;
    QJsonDocument doc(QJsonDocument::fromJson(jsonBa, &err));
    printf("err: %s %d\n", qPrintable(err.errorString()), err.offset);
    QJsonObject obj = doc.object();
    printf("obj is empty: %d\n", obj.isEmpty());
    QJsonObject payload = obj["payload"].toObject();
    printf("payload is empty: %d, orders is array: %d\n", payload.isEmpty(), payload["orders"].isArray());
    QJsonArray arr = payload["orders"].toArray();
    for (int i = 0; i < arr.size(); ++i)
      printf("%d\n", i);
    

    Works perfectly fine for me ...



  • @Christian-Ehrlicher I actually did write many different tests, however none of them worked.

    I managed to fix the issue though.

    The actual problem was that I sent empty data to the QJsonDocument, and obviously that doesn't work.
    The data actually comes from a QNetworkReply, and apparently calling readAll() actually removes the data located in the reply, so calling readAll() twice results in it returning an empty array the second time. (which is what I did)
    I then passed that empty array to QJsonDocument, which was passed to the function.

    I said earlier that using value[0]["platinum"].toInt() worked. Turns out it actually didn't.
    What I actually did when I thought it worked was this:

    qDebug() << "Platinum: " << value[0]["platinum"].toInt(11);
    

    For some reason I decided to put 11 as a default value in toInt() (I'm not sure what I was thinking when I did that, and I have no idea how I didn't notice it until now). So no matter if it succeeded or failed it would always print the seemingly valid value 11 to the console (which matched the value in the Json data), which tricked me into thinking that the QJsonDocument was actually valid, when it in reality was not.


  • Qt Champions 2019

    That's why there is QJsonParseError as shown in my example :)

    /edit: please mark the thread as solved if all works now as expected.


Log in to reply