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

QJSValue to json string (stringify) [Solved]



  • Is there a way to convert a QJSValue object to a json string?

    What I'm trying to do:
    Send a QVariant object formatted as a QJSValue object over a TCP connection from a TCP Service written using Qt 5.4 to a TCP client written using Qt 4.8.

    Problems:
    Qt 4.8 does not have QJSValue objects. There is no easy was to create a json string from a QJSValue object.

    Plan:
    Convert the QJSValue to a json string then send the message to the client. The client can then convert the json string back to a QVariant.


  • Lifetime Qt Champion

    Hi,

    IIRC, there was an external module call QJson for Qt 4 that could be of interest.

    Hope it helps


  • Moderators

    @bundickt said:

    Is there a way to convert a QJSValue object to a json string?

    Yes. QJsonDocument::toJson() produces a JSON string.



  • @JKSH

    I don't have a QJsonDocument object. I have a QJSValue object. The QJSValue object is being created by the Qt Quick engine.

    I create a Qt Quick plugin that creates a TCP server that allows the QML developers to send object to the connect clients:

    c++

    Q_INVOKABLE void sendMessage(QString clientId, QVariant data);
    

    qml

    sendMessage("client1", {key1: "value1", key2: "value2"});
    

    data will be of type QJSValue.


  • Moderators

    @bundickt said:

    I don't have a QJsonDocument object. I have a QJSValue object.

    That's not a problem. We can convert it.

    c++
    Q_INVOKABLE void sendMessage(QString clientId, QVariant data);

    qml
    sendMessage("client1", {key1: "value1", key2: "value2"});

    data will be of type QJSValue.

    Notice that your data is inside a QVariant. So, use QJsonDocument::fromVariant() to create your JSON document, and then turn it into a string using QJsonDocument::toJson(). This works if data is a JavaScript object or JavaScript array.



  • @JKSH

    Thanks for your help. The documentation for QJsonDocument says the QVariant must be one of the following types: QVariantMap, QVariantList or QStringList. However, the QVariant object I have is a QJSValue. I tested it and I get an invalid QJsonDocument. After doing a little experimentation I was able to get a JSON string.

    Code:

    void MyTcpServer::sendMessage(QString clientId, QVariant data) {
        QJsonDocument jsonDoc = QJsonDocument::fromVariant(data.value<QJSValue>().toVariant());
        qDebug() << "json[" <<  jsonDoc.toJson() << "]";
        ....
    

    It looks like data.value<QJSValue>().toVariant() convert the QJSValue variant to a QVariantMap variant.


  • Moderators

    @bundickt

    You're welcome, and I'm glad you've found a solution.

    The documentation for QJsonDocument says the QVariant must be one of the following types: QVariantMap, QVariantList or QStringList. However, the QVariant object I have is a QJSValue. I tested it and I get an invalid QJsonDocument.
    ...
    It looks like data.value<QJSValue>().toVariant() convert the QJSValue variant to a QVariantMap variant.

    That's interesting. A QJSValue is simply a wrapper. If your QJSValue contains a JavaScript object, then it should already be stored as a QVariantMap.

    Out of curiosity, could you run the following code and share the output?

    void MyTcpServer::sendMessage(QString clientId, QVariant data) {
        qDebug() << data;
        ...
    

    QJSValue stores the following datatypes like this:

    • JavaScript boolean -> bool
    • JavaScript number -> int/double
    • JavaScript string -> QString
    • JavaScript array -> QVariantList
    • JavaScript object -> QVariantMap
    • QObject -> QObject*

    So, I expected your output to be: QVariant(QVariantMap, QMap(("key1", QVariant(QString, "value1") ) ( "key2" , QVariant(QString, "value2") ) ) )



  • @JKSH

    The output of qDebug() << data; is:

    QVariant(QJSValue, )
    

    The output of data.value<QJSValue>().toVariant() is:

    QVariant(QVariantMap, QMap((key1, QVariant(QString, value1) ) ( key2 ,  QVariant(QString, value2) ) ) )
    

  • Moderators

    @bundickt said:

    @JKSH

    The output of qDebug() << data; is:

    QVariant(QJSValue, )
    

    The output of data.value<QJSValue>().toVariant() is:

    QVariant(QVariantMap, QMap((key1, QVariant(QString, value1) ) ( key2 ,  QVariant(QString, value2) ) ) )
    

    Ah, right. I thought the QML engine would automatically convert the QJSValue to a QVariantMap, but you had to do the conversion yourself.

    Thank you for sharing your findings!