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. QJsonObject [] operator
Forum Update on Tuesday, May 27th 2025

QJsonObject [] operator

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 1.8k Views 1 Watching
  • 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.
  • V Offline
    V Offline
    VRHans
    wrote on 24 Jul 2018, 12:26 last edited by
    #1

    Using some very simple JSON:

    {
        "client": "Manager",
        "clientversion": "0.1",
        "guid": "414a8189-4850-42c1-82eb-223d8f663e11",
        "message": {
            "mversion": "1.0",
            "type": "debug"
        },
        "operatingsystem": "Windows 10 (10.0)",
        "processid": 4352,
        "sdkversion": "1.2.1+965",
        "timezone": "-4",
        "wversion": "1.0"
    }
    

    If I parse this and get the QJsonObject representing the base object - everything works as expected when querying for the presence of a key using [], e.g:

    if( oBaseJsonObject["this_prop_does_not_exist"] == QJsonValue::Undefined )

    The above will evaluate to true.

    But when I child message object as below:

    if( oBaseJsonObject["message"] != QJsonValue::Undefined )
    {
        QJsonObject oMessageJsonObject = oBaseJsonObject["message"].toObject();
    }
    

    I obtain another valid JSON object - but the [] operator no longer works correctly (as far as I can tell.)

    Executing:

    if( oMessageJsonObject["this_prop_does_not_exist"] == QJsonValue::Undefined )

    Evaluates to false.

    If I obtain the value for the key that does not exist - I get an empty string.

    If I enumerate through the ::keys() collection on the oMessageJsonObject, the expected message and type keys evaluate properly and have their associated values.

    If I use the ::value( key ) method on the oMessageJsonObject - it will evaluate properly for the key that does not exist.

    Is this a bug in the [] operator or am I missing something. It works as expected on the first level, but not as I expected on the nested object. I'm no JSON expert so maybe there's some thing about treating nested objects as arrays and all keys are treated as empty/NULL values instead of Undefined...?

    Thanks,

    Hans
    
    J 1 Reply Last reply 24 Jul 2018, 12:36
    0
    • V VRHans
      24 Jul 2018, 12:26

      Using some very simple JSON:

      {
          "client": "Manager",
          "clientversion": "0.1",
          "guid": "414a8189-4850-42c1-82eb-223d8f663e11",
          "message": {
              "mversion": "1.0",
              "type": "debug"
          },
          "operatingsystem": "Windows 10 (10.0)",
          "processid": 4352,
          "sdkversion": "1.2.1+965",
          "timezone": "-4",
          "wversion": "1.0"
      }
      

      If I parse this and get the QJsonObject representing the base object - everything works as expected when querying for the presence of a key using [], e.g:

      if( oBaseJsonObject["this_prop_does_not_exist"] == QJsonValue::Undefined )

      The above will evaluate to true.

      But when I child message object as below:

      if( oBaseJsonObject["message"] != QJsonValue::Undefined )
      {
          QJsonObject oMessageJsonObject = oBaseJsonObject["message"].toObject();
      }
      

      I obtain another valid JSON object - but the [] operator no longer works correctly (as far as I can tell.)

      Executing:

      if( oMessageJsonObject["this_prop_does_not_exist"] == QJsonValue::Undefined )

      Evaluates to false.

      If I obtain the value for the key that does not exist - I get an empty string.

      If I enumerate through the ::keys() collection on the oMessageJsonObject, the expected message and type keys evaluate properly and have their associated values.

      If I use the ::value( key ) method on the oMessageJsonObject - it will evaluate properly for the key that does not exist.

      Is this a bug in the [] operator or am I missing something. It works as expected on the first level, but not as I expected on the nested object. I'm no JSON expert so maybe there's some thing about treating nested objects as arrays and all keys are treated as empty/NULL values instead of Undefined...?

      Thanks,

      Hans
      
      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 24 Jul 2018, 12:36 last edited by jsulm
      #2

      @VRHans Why don't you use http://doc.qt.io/qt-5/qjsonobject.html#contains instead?
      Also you can use http://doc.qt.io/qt-5/qjsonvalue.html#isObject to check whether it is an object if it exists.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      V 1 Reply Last reply 24 Jul 2018, 12:38
      0
      • J jsulm
        24 Jul 2018, 12:36

        @VRHans Why don't you use http://doc.qt.io/qt-5/qjsonobject.html#contains instead?
        Also you can use http://doc.qt.io/qt-5/qjsonvalue.html#isObject to check whether it is an object if it exists.

        V Offline
        V Offline
        VRHans
        wrote on 24 Jul 2018, 12:38 last edited by
        #3

        @jsulm I have a work around using ::value( key ) already, I was trying to figure out if this is a bug or I'm making assumptions about something in JSON where different behavior at different nesting levels IS expected behavior. Thanks though :)

        J 1 Reply Last reply 24 Jul 2018, 12:41
        1
        • V VRHans
          24 Jul 2018, 12:38

          @jsulm I have a work around using ::value( key ) already, I was trying to figure out if this is a bug or I'm making assumptions about something in JSON where different behavior at different nesting levels IS expected behavior. Thanks though :)

          J Offline
          J Offline
          jsulm
          Lifetime Qt Champion
          wrote on 24 Jul 2018, 12:41 last edited by
          #4

          @VRHans Sounds like it could indeed be a bug. You can check on Qt bugtracker and file a bug there.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • V Offline
            V Offline
            VRonin
            wrote on 24 Jul 2018, 13:12 last edited by VRonin
            #5

            What type is oBaseJsonObject (please include all qualifiers)?

            Declaring oMessageJsonObject as const QJsonObject instead should fix your problem.

            Basically if you call operator[](QString) on a non-const QJsonObject the method called will be http://doc.qt.io/qt-5/qjsonobject.html#operator-5b-5d-2 and not http://doc.qt.io/qt-5/qjsonobject.html#operator-5b-5d

            This is the same problem you have in associative containers and is described in http://doc.qt.io/qt-5/qmap.html#details

            In general, we recommend that you use contains() and value() rather than operator for looking up a key in a map. The reason is that operator silently inserts an item into the map if no item exists with the same key (unless the map is const). For example, the following code snippet will create 1000 items in memory:

            // WRONG
            QMap<int, QWidget *> map;
            ...
            for (int i = 0; i < 1000; ++i) {
                if (map[i] == okButton)
                    cout << "Found button at index " << i << endl;
            }
            

            To avoid this problem, replace map[i] with map.value(i) in the code above.

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            V 1 Reply Last reply 24 Jul 2018, 13:16
            4
            • V VRonin
              24 Jul 2018, 13:12

              What type is oBaseJsonObject (please include all qualifiers)?

              Declaring oMessageJsonObject as const QJsonObject instead should fix your problem.

              Basically if you call operator[](QString) on a non-const QJsonObject the method called will be http://doc.qt.io/qt-5/qjsonobject.html#operator-5b-5d-2 and not http://doc.qt.io/qt-5/qjsonobject.html#operator-5b-5d

              This is the same problem you have in associative containers and is described in http://doc.qt.io/qt-5/qmap.html#details

              In general, we recommend that you use contains() and value() rather than operator for looking up a key in a map. The reason is that operator silently inserts an item into the map if no item exists with the same key (unless the map is const). For example, the following code snippet will create 1000 items in memory:

              // WRONG
              QMap<int, QWidget *> map;
              ...
              for (int i = 0; i < 1000; ++i) {
                  if (map[i] == okButton)
                      cout << "Found button at index " << i << endl;
              }
              

              To avoid this problem, replace map[i] with map.value(i) in the code above.

              V Offline
              V Offline
              VRHans
              wrote on 24 Jul 2018, 13:16 last edited by
              #6

              @VRonin said in QJsonObject [] operator:

              http://doc.qt.io/qt-5/qjsonobject.html#operator-5b-5d-2

              Totally makes sense - my mistake for not treating it like std::map (and other associative containers as you mentioned.)

              By design.

              Cheers,

              Hans
              
              1 Reply Last reply
              1

              1/6

              24 Jul 2018, 12:26

              • Login

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