0

I have a Json file to read and display on UI. Reading is fine but when I tried to update value wheelbase, code runs with no errors but it does not update the Json

Json file example

{
"$type": "SystemList",
    "$values": [
        {
            "chassicId": 1000,
            "wheelbase": 98

        },
        {
            "chassicId": 1001,
            "wheelbase": 102
        }
     ]
}

This is the write function. What I have tried is to parse the Json file to the QJsonArray, then iterates and map with the function id parameter in order to update the wheelbase value.

void updateWheelbase(const int& id)
{
   
        updatedWheelbase = dialog.wheelbaseInput().toDouble();
        QFile file("json file path");
        file.open(QIODevice::ReadOnly | QIODevice::Text);
        QByteArray jsonData = file.readAll();
        file.close();

        QJsonDocument itemDoc = QJsonDocument::fromJson(jsonData);
        QJsonObject rootObject = itemDoc.object();

        QJsonArray valuesArray = rootObject.value("$values").toArray();

        //get a copy of the QJsonObject
        QJsonObject obj;
        for (auto v: valuesArray) {
            QJsonObject o = v.toObject();
            if (o.value("chassicId").toInt() == id) {
                obj = o;
                break;
            }
        }

        // modify the object
        obj["wheelbase"] = updatedWheelbase;
        int position = 0;

        // erase the old instance of the object
        for (auto it = valuesArray.begin(); it != valuesArray.end(); ++it) {
            QJsonObject obj = (*it).toObject();
            if (obj.value("chassicId").toInt() == id) {
                valuesArray.erase(it);

                //assign the array copy which has the object deleted
                rootObject["$value"] = valuesArray;
                break;
            }
            position++;
        }

        // add the modified QJsonObject
        valuesArray.append(obj);

        // replace the original array with the array containing our modified threshold object
        itemDoc.setObject(rootObject);

        file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
        file.write(itemDoc.toJson());
        file.close();
}
Neung Chung
  • 159
  • 1
  • 1
  • 10

1 Answers1

1

You should place rootObject["$value"] = valuesArray; after the valuesArray.append(obj);. In your example, when append obj to valuesArray, you just update valuesArray, have not update rootObject.

#include <QtWidgets/QApplication>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

void updateWheelbase()
{
    int id = 1001;
    double updatedWheelbase = 1.1;
    QFile file("./Debug/a.json");
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    QByteArray jsonData = file.readAll();
    file.close();

    QJsonDocument itemDoc = QJsonDocument::fromJson(jsonData);
    QJsonObject rootObject = itemDoc.object();

    QJsonArray valuesArray = rootObject.value("$values").toArray();

    //get a copy of the QJsonObject
    QJsonObject obj;
    for (auto v : valuesArray) {
        QJsonObject o = v.toObject();
        if (o.value("chassicId").toInt() == id) {
            obj = o;
            break;
        }
    }

    // modify the object
    obj["wheelbase"] = updatedWheelbase;
    int position = 0;

    // erase the old instance of the object
    for (auto it = valuesArray.begin(); it != valuesArray.end(); ++it) {
        QJsonObject obj = (*it).toObject();
        if (obj.value("chassicId").toInt() == id) {
            valuesArray.erase(it);

            //assign the array copy which has the object deleted
            rootObject["$values"] = valuesArray;
            break;
        }
        position++;
    }

    // add the modified QJsonObject
    valuesArray.append(obj);
    rootObject["$values"] = valuesArray;
    // replace the original array with the array containing our modified threshold object
    itemDoc.setObject(rootObject);

    file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
    file.write(itemDoc.toJson());
    file.close();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    updateWheelbase();
    return a.exec();
}
Ye.Feng
  • 709
  • 6
  • 9
  • Yes you are right, I should have updated the rootObject. Tried your solution but still did not work. – Neung Chung Oct 10 '21 at 14:54
  • I just checked and realized that when writing to the json file, the QIODevice::write: device not open, does that mean I don't have an access right to write on the file? – Neung Chung Oct 11 '21 at 04:05
  • I tried your code, and changed what I said, it works fine. If yours does not work, it may be a problem with the file path. @NeungChung – Ye.Feng Oct 11 '21 at 05:08
  • Where did you store the json file? – Neung Chung Oct 11 '21 at 06:29
  • I add my code in answer, you can compare it. @NeungChung – Ye.Feng Oct 11 '21 at 06:47
  • I debug my code and see that `file.open(QIODevice::ReadOnly | QIODevice::Text);` returns true, but `file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);` returns false – Neung Chung Oct 11 '21 at 06:59
  • You can try to run the program with administrator rights, or root privileges, if you are using a Linux system. – Ye.Feng Oct 11 '21 at 07:34
  • It worked now, thanks a lot for your help, will mark your code as the solution :) – Neung Chung Oct 11 '21 at 08:24