Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. adding to json file without deleting the content
Forum Updated to NodeBB v4.3 + New Features

adding to json file without deleting the content

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 784 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kris Revi
    wrote on 22 Sept 2021, 11:50 last edited by
    #1

    aaargh im blinded....
    what am i doing wrong here? im trying to add to my json file! currently it deletes what is in the json and then sets the new entry in :/

    bool DeviceData::devicedataupdated()
    {
        DeviceDataDebugger.LevelInfo("DEVICEDATA", "INIT", "Adding New Device", "!");
    
        QFile file("devices.json");
    
        if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
        {
            DeviceDataDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or read the file", "!");
            return false;
        }
    
        QJsonParseError *error = new QJsonParseError();
        QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
        file.close();
    
        QJsonObject newDevice;
    
        newDevice.insert("IPA",      "newdevice");
        newDevice.insert("Icon",     "fa_bolt");
        newDevice.insert("Name",     "New Device");
        newDevice.insert("Status",   "online");
        newDevice.insert("Type",     "Strip");
        newDevice.insert("UVLights", "false");
    
        QJsonArray allEntriesList = inputJsonDoc.array();
        allEntriesList.push_back(newDevice);
    
        QJsonObject outputJsonObject ;
        outputJsonObject["New Device"] = allEntriesList;
    
        QJsonDocument outputJsonDoc;
        outputJsonDoc.setObject(outputJsonObject);
    
        if ( !file.open(QIODevice::WriteOnly | QIODevice::Text) )
        {
            DeviceDataDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
            return false;
        }
    
        file.write(outputJsonDoc.toJson());
        file.close();
        return true;
        DeviceDataDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
    }
    
    1 Reply Last reply
    0
    • A AxelVienna
      22 Sept 2021, 12:40

      Ah, I overlooked something. You need to read the inputJsonDoc into inputJsonObject first.
      Replace

      QJsonObject inputJsonObject;
      

      with

      QJsonObject inputJsonObject = inputJsonDoc.object();
      

      Sorry about that.

      K Offline
      K Offline
      Kris Revi
      wrote on 22 Sept 2021, 12:59 last edited by
      #6

      @AxelVienna thank you so much for the help! :)

      ANSWER

      bool MainWindow::addNewDevice()
      {
          AddDeviceDebugger.LevelInfo("DEVICEDATA", "INIT", "Adding New Device", "!");
      
          QFile file("devices.json");
      
          if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
          {
              AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or read the file", "!");
              return false;
          }
      
          QJsonParseError *error = new QJsonParseError();
          QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
          file.close();
      
          QJsonObject newDevice;
      
          newDevice.insert("IPA",      "newdevice");
          newDevice.insert("Icon",     "fa_bolt");
          newDevice.insert("Name",     "New Device");
          newDevice.insert("Status",   "online");
          newDevice.insert("Type",     "Strip");
          newDevice.insert("UVLights", "false");
      
          QJsonObject inputJsonObject = inputJsonDoc.object();
          inputJsonObject["New Device"] = newDevice;
      
          QJsonDocument outputJsonDoc;
          outputJsonDoc.setObject(inputJsonObject);
      
          if ( !file.open(QIODevice::WriteOnly | QIODevice::Text ) )
          {
              AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
              return false;
          }
      
          file.write(outputJsonDoc.toJson());
          file.close();
          return true;
          AddDeviceDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
      }
      
      1 Reply Last reply
      0
      • K Offline
        K Offline
        Kris Revi
        wrote on 22 Sept 2021, 12:00 last edited by
        #2

        how it looks currently

        {
            "Studio Lights": {
                "IPA": "studiolights",
                "Icon": "fa_bolt",
                "Name": "Studio Lights",
                "Status": "online",
                "Type": "Strip",
                "UVLights": "false"
            }
        }
        

        how it should look after adding/appending

        {
            "Studio Lights": {
                "IPA": "studiolights",
                "Icon": "fa_bolt",
                "Name": "Studio Lights",
                "Status": "online",
                "Type": "Strip",
                "UVLights": "false"
            }
            "newdevice": {
                "IPA": "studiolights",
                "Icon": "fa_bolt",
                "Name": "New Device",
                "Status": "online",
                "Type": "Strip",
                "UVLights": "false"
            }
        }
        
        1 Reply Last reply
        0
        • A Offline
          A Offline
          AxelVienna
          wrote on 22 Sept 2021, 12:11 last edited by
          #3

          Your JSON file contains an object, not an array.
          The line...

          QJsonArray allEntriesList = inputJsonDoc.array();
          

          ...will therefore create an empty allEntriesList, which you then append to newDevice.
          The consequence is that newDevice contains nothing but the new device. Change the code as follows to fix the misbehavior:

          (...)
          QJsonObject newDevice;
          
              newDevice.insert("IPA",      "newdevice");
              newDevice.insert("Icon",     "fa_bolt");
              newDevice.insert("Name",     "New Device");
              newDevice.insert("Status",   "online");
              newDevice.insert("Type",     "Strip");
              newDevice.insert("UVLights", "false");
          
              /* changes start here */
              // QJsonArray allEntriesList = inputJsonDoc.array();
              // allEntriesList.push_back(newDevice);
          
              // QJsonObject outputJsonObject ;
              // outputJsonObject["New Device"] = allEntriesList;
              inputJsonObject["New Device"] = newDevice;
          
              QJsonDocument outputJsonDoc;
              // outputJsonDoc.setObject(outputJsonObject);
              outputJsonDoc.setObject(inputJsonObject);
              /* no more changes from here */
              
              if ( !file.open(QIODevice::WriteOnly | QIODevice::Text) )
              {
                  DeviceDataDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
                  return false;
              }
          

          C++ and Python walk into a bar. C++ reuses the first glass.

          K 1 Reply Last reply 22 Sept 2021, 12:25
          1
          • A AxelVienna
            22 Sept 2021, 12:11

            Your JSON file contains an object, not an array.
            The line...

            QJsonArray allEntriesList = inputJsonDoc.array();
            

            ...will therefore create an empty allEntriesList, which you then append to newDevice.
            The consequence is that newDevice contains nothing but the new device. Change the code as follows to fix the misbehavior:

            (...)
            QJsonObject newDevice;
            
                newDevice.insert("IPA",      "newdevice");
                newDevice.insert("Icon",     "fa_bolt");
                newDevice.insert("Name",     "New Device");
                newDevice.insert("Status",   "online");
                newDevice.insert("Type",     "Strip");
                newDevice.insert("UVLights", "false");
            
                /* changes start here */
                // QJsonArray allEntriesList = inputJsonDoc.array();
                // allEntriesList.push_back(newDevice);
            
                // QJsonObject outputJsonObject ;
                // outputJsonObject["New Device"] = allEntriesList;
                inputJsonObject["New Device"] = newDevice;
            
                QJsonDocument outputJsonDoc;
                // outputJsonDoc.setObject(outputJsonObject);
                outputJsonDoc.setObject(inputJsonObject);
                /* no more changes from here */
                
                if ( !file.open(QIODevice::WriteOnly | QIODevice::Text) )
                {
                    DeviceDataDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
                    return false;
                }
            
            K Offline
            K Offline
            Kris Revi
            wrote on 22 Sept 2021, 12:25 last edited by
            #4

            @AxelVienna so the new code looks like this

            bool DeviceData::devicedataupdated()
            {
                DeviceDataDebugger.LevelInfo("DEVICEDATA", "INIT", "Adding New Device", "!");
            
                QFile file("devices.json");
            
                if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
                {
                    DeviceDataDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or read the file", "!");
                    return false;
                }
            
                QJsonParseError *error = new QJsonParseError();
                QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
                file.close();
            
                QJsonObject newDevice;
            
                newDevice.insert("IPA",      "newdevice");
                newDevice.insert("Icon",     "fa_bolt");
                newDevice.insert("Name",     "New Device");
                newDevice.insert("Status",   "online");
                newDevice.insert("Type",     "Strip");
                newDevice.insert("UVLights", "false");
            
                QJsonObject inputJsonObject;
                inputJsonObject["New Device"] = newDevice;
            
                QJsonDocument outputJsonDoc;
                outputJsonDoc.setObject(inputJsonObject);
            
                if ( !file.open(QIODevice::WriteOnly | QIODevice::Text ) )
                {
                    DeviceDataDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
                    return false;
                }
            
                file.write(outputJsonDoc.toJson());
                file.close();
                return true;
                DeviceDataDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
            }
            

            did i miss something? cause now "New Device" just replaces the "Studio Lights" entry!

            1 Reply Last reply
            0
            • A Offline
              A Offline
              AxelVienna
              wrote on 22 Sept 2021, 12:40 last edited by
              #5

              Ah, I overlooked something. You need to read the inputJsonDoc into inputJsonObject first.
              Replace

              QJsonObject inputJsonObject;
              

              with

              QJsonObject inputJsonObject = inputJsonDoc.object();
              

              Sorry about that.

              C++ and Python walk into a bar. C++ reuses the first glass.

              K 2 Replies Last reply 22 Sept 2021, 12:59
              1
              • A AxelVienna
                22 Sept 2021, 12:40

                Ah, I overlooked something. You need to read the inputJsonDoc into inputJsonObject first.
                Replace

                QJsonObject inputJsonObject;
                

                with

                QJsonObject inputJsonObject = inputJsonDoc.object();
                

                Sorry about that.

                K Offline
                K Offline
                Kris Revi
                wrote on 22 Sept 2021, 12:59 last edited by
                #6

                @AxelVienna thank you so much for the help! :)

                ANSWER

                bool MainWindow::addNewDevice()
                {
                    AddDeviceDebugger.LevelInfo("DEVICEDATA", "INIT", "Adding New Device", "!");
                
                    QFile file("devices.json");
                
                    if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
                    {
                        AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or read the file", "!");
                        return false;
                    }
                
                    QJsonParseError *error = new QJsonParseError();
                    QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
                    file.close();
                
                    QJsonObject newDevice;
                
                    newDevice.insert("IPA",      "newdevice");
                    newDevice.insert("Icon",     "fa_bolt");
                    newDevice.insert("Name",     "New Device");
                    newDevice.insert("Status",   "online");
                    newDevice.insert("Type",     "Strip");
                    newDevice.insert("UVLights", "false");
                
                    QJsonObject inputJsonObject = inputJsonDoc.object();
                    inputJsonObject["New Device"] = newDevice;
                
                    QJsonDocument outputJsonDoc;
                    outputJsonDoc.setObject(inputJsonObject);
                
                    if ( !file.open(QIODevice::WriteOnly | QIODevice::Text ) )
                    {
                        AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
                        return false;
                    }
                
                    file.write(outputJsonDoc.toJson());
                    file.close();
                    return true;
                    AddDeviceDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
                }
                
                1 Reply Last reply
                0
                • A AxelVienna
                  22 Sept 2021, 12:40

                  Ah, I overlooked something. You need to read the inputJsonDoc into inputJsonObject first.
                  Replace

                  QJsonObject inputJsonObject;
                  

                  with

                  QJsonObject inputJsonObject = inputJsonDoc.object();
                  

                  Sorry about that.

                  K Offline
                  K Offline
                  Kris Revi
                  wrote on 22 Sept 2021, 13:19 last edited by
                  #7

                  @AxelVienna

                  currently working code

                  bool MainWindow::addNewDevice()
                  {
                      AddDeviceDebugger.LevelInfo("DEVICEDATA", "INIT", "Adding New Device", "!");
                  
                      QFile file("devices.json");
                  
                      if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
                      {
                          AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or read the file", "!");
                          return false;
                      }
                  
                      QJsonParseError *error = new QJsonParseError();
                      QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
                      file.close();
                  
                      QJsonObject newDevice;
                  
                      newDevice.insert("IPA",      "newdevice");
                      newDevice.insert("Icon",     "fa_bolt");
                      newDevice.insert("Name",     "New Device");
                      newDevice.insert("Status",   "online");
                      newDevice.insert("Type",     "Strip");
                      newDevice.insert("UVLights", "false");
                  
                      QJsonObject inputJsonObject = inputJsonDoc.object();
                      inputJsonObject["New Device"] = newDevice;
                  
                      QJsonDocument outputJsonDoc;
                      outputJsonDoc.setObject(inputJsonObject);
                  
                      if ( !file.open(QIODevice::WriteOnly | QIODevice::Text ) )
                      {
                          AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
                          return false;
                      }
                  
                      file.write(outputJsonDoc.toJson());
                      file.close();
                      return true;
                      AddDeviceDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
                  }
                  

                  Json befor adding new entry

                  {
                      "Studio Lights": {
                          "IPA": "studiolights",
                          "Icon": "fa_bolt",
                          "Name": "Studio Lights",
                          "Status": "online",
                          "Type": "Strip",
                          "UVLights": "false"
                      }
                  }
                  

                  after adding new entry

                  {
                      "New Device": {
                          "IPA": "newdevice",
                          "Icon": "fa_bolt",
                          "Name": "New Device",
                          "Status": "online",
                          "Type": "Strip",
                          "UVLights": "false"
                      },
                      "Studio Lights": {
                          "IPA": "studiolights",
                          "Icon": "fa_bolt",
                          "Name": "Studio Lights",
                          "Status": "online",
                          "Type": "Strip",
                          "UVLights": "false"
                      }
                  }
                  

                  why does the new entry come ontop and not underneath "Studio Lights" this is annoying when i then update and populate my device list with buttons for each device (from json file) the newly added one will be inserted ontop of the devices already listed :/

                  JonBJ 1 Reply Last reply 22 Sept 2021, 13:31
                  0
                  • K Kris Revi
                    22 Sept 2021, 13:19

                    @AxelVienna

                    currently working code

                    bool MainWindow::addNewDevice()
                    {
                        AddDeviceDebugger.LevelInfo("DEVICEDATA", "INIT", "Adding New Device", "!");
                    
                        QFile file("devices.json");
                    
                        if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
                        {
                            AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or read the file", "!");
                            return false;
                        }
                    
                        QJsonParseError *error = new QJsonParseError();
                        QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
                        file.close();
                    
                        QJsonObject newDevice;
                    
                        newDevice.insert("IPA",      "newdevice");
                        newDevice.insert("Icon",     "fa_bolt");
                        newDevice.insert("Name",     "New Device");
                        newDevice.insert("Status",   "online");
                        newDevice.insert("Type",     "Strip");
                        newDevice.insert("UVLights", "false");
                    
                        QJsonObject inputJsonObject = inputJsonDoc.object();
                        inputJsonObject["New Device"] = newDevice;
                    
                        QJsonDocument outputJsonDoc;
                        outputJsonDoc.setObject(inputJsonObject);
                    
                        if ( !file.open(QIODevice::WriteOnly | QIODevice::Text ) )
                        {
                            AddDeviceDebugger.LevelInfo("DEVICEDATA", "OPEN", "Failed to open and / or write to the file", "!");
                            return false;
                        }
                    
                        file.write(outputJsonDoc.toJson());
                        file.close();
                        return true;
                        AddDeviceDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
                    }
                    

                    Json befor adding new entry

                    {
                        "Studio Lights": {
                            "IPA": "studiolights",
                            "Icon": "fa_bolt",
                            "Name": "Studio Lights",
                            "Status": "online",
                            "Type": "Strip",
                            "UVLights": "false"
                        }
                    }
                    

                    after adding new entry

                    {
                        "New Device": {
                            "IPA": "newdevice",
                            "Icon": "fa_bolt",
                            "Name": "New Device",
                            "Status": "online",
                            "Type": "Strip",
                            "UVLights": "false"
                        },
                        "Studio Lights": {
                            "IPA": "studiolights",
                            "Icon": "fa_bolt",
                            "Name": "Studio Lights",
                            "Status": "online",
                            "Type": "Strip",
                            "UVLights": "false"
                        }
                    }
                    

                    why does the new entry come ontop and not underneath "Studio Lights" this is annoying when i then update and populate my device list with buttons for each device (from json file) the newly added one will be inserted ontop of the devices already listed :/

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on 22 Sept 2021, 13:31 last edited by
                    #8

                    @Kris-Revi
                    JSON object attributes are unordered. You cannot force it to output them in any particular order.

                    If you must know/maintain an order per your example, you would have to e.g. add a further attribute into each object to indicate its order, and use that during restore. Or store as an array/list, which I think do have & preserve order.

                    Tiny points about your code:

                        return true;
                        AddDeviceDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
                    

                    Ought generate a compiler warning. Reverse the order of the lines.

                        QJsonParseError *error = new QJsonParseError();
                        QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
                    

                    This leaks the newed QJsonParseError. Either delete it, or simpler allocate on stack and pass address:

                        QJsonParseError error;
                        QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), &error);
                    
                    K 1 Reply Last reply 22 Sept 2021, 13:40
                    1
                    • JonBJ JonB
                      22 Sept 2021, 13:31

                      @Kris-Revi
                      JSON object attributes are unordered. You cannot force it to output them in any particular order.

                      If you must know/maintain an order per your example, you would have to e.g. add a further attribute into each object to indicate its order, and use that during restore. Or store as an array/list, which I think do have & preserve order.

                      Tiny points about your code:

                          return true;
                          AddDeviceDebugger.LevelSuccess("DEVICEDATA", "SUCCESS", "Created new device", "!");
                      

                      Ought generate a compiler warning. Reverse the order of the lines.

                          QJsonParseError *error = new QJsonParseError();
                          QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), error);
                      

                      This leaks the newed QJsonParseError. Either delete it, or simpler allocate on stack and pass address:

                          QJsonParseError error;
                          QJsonDocument inputJsonDoc = QJsonDocument::fromJson(file.readAll(), &error);
                      
                      K Offline
                      K Offline
                      Kris Revi
                      wrote on 22 Sept 2021, 13:40 last edited by
                      #9

                      @JonB said in adding to json file without deleting the content:

                      add a further attribute into each object to indicate its order

                      like what and how does that work?

                      ty for the pointers, they are fixed now :)

                      JonBJ 1 Reply Last reply 22 Sept 2021, 14:34
                      0
                      • K Kris Revi
                        22 Sept 2021, 13:40

                        @JonB said in adding to json file without deleting the content:

                        add a further attribute into each object to indicate its order

                        like what and how does that work?

                        ty for the pointers, they are fixed now :)

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on 22 Sept 2021, 14:34 last edited by JonB
                        #10

                        @Kris-Revi said in adding to json file without deleting the content:

                        like what and how does that work?

                        All I meant was you'd have to make your saved JSON like, say,

                        {
                            "New Device": {
                                "IPA": "newdevice",
                                ...,
                                "Order": 1
                            },
                            "Studio Lights": {
                                "IPA": "studiolights",
                                ...,
                                "Order": 0
                            }
                        }
                        

                        So I made each element have an Order attribute, counting from 0 upward like an array for the order they were in when I saved. Which as shown above happens randomly to have come out not in that order when saved. Now it's your responsibility when reloading and recreating "populate my device list with buttons for each device" to look at the Order attribute on each one and use that to order your device list as you want it to be.

                        The other way, if order is so important, is not to store as just an object with an arbitrary list of named attributes ( "New Device":, "Studio Lights": ...) as you have done here, precisely because you cannot order those. Instead store as an array/list like:

                        {
                          [
                            {
                                "Name":  "New Device",
                                "IPA": "newdevice",
                                ...,
                                "Order": 1
                            },
                            {
                                "Name":  "Studio Lights",
                                "IPA": "studiolights",
                                ...,
                                "Order": 0
                            }
                          ]
                        }
                        

                        This is an array/list of objects, so it does have an order which is preserved on save/restore. Of course, that then takes you back to your original code as to how to locate an object element by Name, but that's the price you pay if ordering is important to you.

                        1 Reply Last reply
                        1

                        4/10

                        22 Sept 2021, 12:25

                        • Login

                        • Login or register to search.
                        4 out of 10
                        • First post
                          4/10
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved