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!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.