Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. bug in a JS function

bug in a JS function

Scheduled Pinned Locked Moved Solved QML and Qt Quick
17 Posts 2 Posters 1.1k 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.
  • M Offline
    M Offline
    mzimmers
    wrote on 26 Apr 2024, 18:58 last edited by
    #1

    Hi all -

    I've written a callback function that has a bug in it. I've traced it to a single line, but can't see what's wrong with it. I apologize for the verbosity of the variable names.

    console.log("EquipmentSelectValves.qml.replaceValve(): i is " + i)
    console.log("EquipmentSelectValves.qml.replaceValve(): unassignedValves is " + unassignedValves)
    
    var pumpUuid = equipmentCopy.uuid
    console.log("EquipmentSelectValves.qml.replaceValve(): pumpUuid is " + pumpUuid)
    
    var assignedValves = []
    console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves is an array: " + Array.isArray(assignedValves))
    
    assignedValves = outcome.valveConfigurationList
    console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves size is " + assignedValves.length)
    console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves (before) is " + assignedValves)
    
    var indexToReplace = assignedValves.indexOf(modelData)
    console.log("EquipmentSelectValves.qml.replaceValve(): indexToReplace is " + indexToReplace)
    
    var newValveUuid = unassignedValves[i]
    console.log("EquipmentSelectValves.qml.replaceValve(): newValveUuid is " + newValveUuid)
    
    assignedValves[indexToReplace] = newValveUuid // THIS LINE IS CAUSING THE PROBLEM.
    console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves (after) is " + assignedValves)
    
    outcome.valveConfigurationList = assignedValves
    console.log("EquipmentSelectValves.qml.replaceValve(): outcome.valveConfigurationList is " + outcome.valveConfigurationList) // THIS IS THE LINE WITH THE ERROR BELOW.
    

    Here's the console output:

    qml: EquipmentSelectValves.qml.replaceValve(): i is 0
    qml: EquipmentSelectValves.qml.replaceValve(): unassignedValves is {fb4f3c69-312e-4399-8d80-ffabe2deab9f},{fe93c695-7f7c-4af5-8ff8-8010fa6db546}
    qml: EquipmentSelectValves.qml.replaceValve(): pumpUuid is {a277e2f8-5f30-4197-8092-d6f3c345f85d}
    qml: EquipmentSelectValves.qml.replaceValve(): assignedValves is an array: true
    qml: EquipmentSelectValves.qml.replaceValve(): assignedValves size is 2
    qml: EquipmentSelectValves.qml.replaceValve(): assignedValves (before) is {821856d4-deb1-4b55-9ba2-0fc4fee11ad2},{68dbce5b-c0c3-4f95-a9f5-7db9f0351421}
    qml: EquipmentSelectValves.qml.replaceValve(): indexToReplace is 1
    qml: EquipmentSelectValves.qml.replaceValve(): newValveUuid is {fb4f3c69-312e-4399-8d80-ffabe2deab9f}
    qml: EquipmentSelectValves.qml.replaceValve(): assignedValves (after) is {821856d4-deb1-4b55-9ba2-0fc4fee11ad2},{fb4f3c69-312e-4399-8d80-ffabe2deab9f}
    qrc:/qt/qml/NgaIcdFw/qml/equipment/EquipmentSelectValves.qml:202: ReferenceError: outcome is not defined
    

    It's as though something in my routine is clobbering itself. Can anyone see something I'm doing wrong here?

    Thanks...

    M 1 Reply Last reply 26 Apr 2024, 22:01
    0
    • J Offline
      J Offline
      JKSH
      Moderators
      wrote on 3 May 2024, 17:00 last edited by
      #15

      Looks like you've found an interesting bug related to Components accessing external IDs.

      Add pragma ComponentBehavior: Bound to the top of EquipmentSelectValves.qml (see https://doc.qt.io/qt-6/qtqml-documents-structure.html#componentbehavior ). This makes the QML engine a bit stricter though, so you need to also mark your delegate's modelData and index properties as required property (see the examples at https://doc.qt.io/qt-6/qtquick-modelviewsdata-modelview.html#models ). This is not necessarily a bad thing, as it enforces good practice.

      Note: After this, your example will no longer complain that outcome is not defined, but it will complain about equipmentModel because that is truly not defined anywhere in your example.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      M 1 Reply Last reply 3 May 2024, 18:43
      1
      • M mzimmers
        26 Apr 2024, 18:58

        Hi all -

        I've written a callback function that has a bug in it. I've traced it to a single line, but can't see what's wrong with it. I apologize for the verbosity of the variable names.

        console.log("EquipmentSelectValves.qml.replaceValve(): i is " + i)
        console.log("EquipmentSelectValves.qml.replaceValve(): unassignedValves is " + unassignedValves)
        
        var pumpUuid = equipmentCopy.uuid
        console.log("EquipmentSelectValves.qml.replaceValve(): pumpUuid is " + pumpUuid)
        
        var assignedValves = []
        console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves is an array: " + Array.isArray(assignedValves))
        
        assignedValves = outcome.valveConfigurationList
        console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves size is " + assignedValves.length)
        console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves (before) is " + assignedValves)
        
        var indexToReplace = assignedValves.indexOf(modelData)
        console.log("EquipmentSelectValves.qml.replaceValve(): indexToReplace is " + indexToReplace)
        
        var newValveUuid = unassignedValves[i]
        console.log("EquipmentSelectValves.qml.replaceValve(): newValveUuid is " + newValveUuid)
        
        assignedValves[indexToReplace] = newValveUuid // THIS LINE IS CAUSING THE PROBLEM.
        console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves (after) is " + assignedValves)
        
        outcome.valveConfigurationList = assignedValves
        console.log("EquipmentSelectValves.qml.replaceValve(): outcome.valveConfigurationList is " + outcome.valveConfigurationList) // THIS IS THE LINE WITH THE ERROR BELOW.
        

        Here's the console output:

        qml: EquipmentSelectValves.qml.replaceValve(): i is 0
        qml: EquipmentSelectValves.qml.replaceValve(): unassignedValves is {fb4f3c69-312e-4399-8d80-ffabe2deab9f},{fe93c695-7f7c-4af5-8ff8-8010fa6db546}
        qml: EquipmentSelectValves.qml.replaceValve(): pumpUuid is {a277e2f8-5f30-4197-8092-d6f3c345f85d}
        qml: EquipmentSelectValves.qml.replaceValve(): assignedValves is an array: true
        qml: EquipmentSelectValves.qml.replaceValve(): assignedValves size is 2
        qml: EquipmentSelectValves.qml.replaceValve(): assignedValves (before) is {821856d4-deb1-4b55-9ba2-0fc4fee11ad2},{68dbce5b-c0c3-4f95-a9f5-7db9f0351421}
        qml: EquipmentSelectValves.qml.replaceValve(): indexToReplace is 1
        qml: EquipmentSelectValves.qml.replaceValve(): newValveUuid is {fb4f3c69-312e-4399-8d80-ffabe2deab9f}
        qml: EquipmentSelectValves.qml.replaceValve(): assignedValves (after) is {821856d4-deb1-4b55-9ba2-0fc4fee11ad2},{fb4f3c69-312e-4399-8d80-ffabe2deab9f}
        qrc:/qt/qml/NgaIcdFw/qml/equipment/EquipmentSelectValves.qml:202: ReferenceError: outcome is not defined
        

        It's as though something in my routine is clobbering itself. Can anyone see something I'm doing wrong here?

        Thanks...

        M Offline
        M Offline
        mzimmers
        wrote on 26 Apr 2024, 22:01 last edited by
        #2

        I think I found the problem, but I don't understand it. Here's a simplified snippet:

        ListView {
            id: valveList
            model: outcome.valveConfigurationList
            delegate: valveBox
            Component {
                id: valveBox
                TextIconButton {
                    id: textIconButton
                    onClicked: {
                        valvesSideDrawer.open()
                        valvesDrawerView.push("components/EquipmentDrawer.qml",
                                              {
                                                  listModel: unassignedValves,
                                                  titleText: "Valves",
                                                  callback: replaceValve
                                              })
                    }
        
                    function replaceValve(b, i) {
                        outcome.valveConfigurationList = assignedValves
                        console.log("EquipmentSelectValves.qml.replaceValve(): outcome.valveConfigurationList is " + outcome.valveConfigurationList)
        

        Note that I'm trying to modify the model (outcome.valveConfigurationList) from within the delegate. Should this be permitted? The C++ function seems to work correctly when this happens, but I'm wondering if I'm somehow sending the QML engine into the weeds...

        J 1 Reply Last reply 27 Apr 2024, 13:20
        0
        • M mzimmers
          26 Apr 2024, 22:01

          I think I found the problem, but I don't understand it. Here's a simplified snippet:

          ListView {
              id: valveList
              model: outcome.valveConfigurationList
              delegate: valveBox
              Component {
                  id: valveBox
                  TextIconButton {
                      id: textIconButton
                      onClicked: {
                          valvesSideDrawer.open()
                          valvesDrawerView.push("components/EquipmentDrawer.qml",
                                                {
                                                    listModel: unassignedValves,
                                                    titleText: "Valves",
                                                    callback: replaceValve
                                                })
                      }
          
                      function replaceValve(b, i) {
                          outcome.valveConfigurationList = assignedValves
                          console.log("EquipmentSelectValves.qml.replaceValve(): outcome.valveConfigurationList is " + outcome.valveConfigurationList)
          

          Note that I'm trying to modify the model (outcome.valveConfigurationList) from within the delegate. Should this be permitted? The C++ function seems to work correctly when this happens, but I'm wondering if I'm somehow sending the QML engine into the weeds...

          J Offline
          J Offline
          JKSH
          Moderators
          wrote on 27 Apr 2024, 13:20 last edited by
          #3

          @mzimmers How is outcome defined?

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          M 1 Reply Last reply 27 Apr 2024, 13:29
          0
          • J JKSH
            27 Apr 2024, 13:20

            @mzimmers How is outcome defined?

            M Offline
            M Offline
            mzimmers
            wrote on 27 Apr 2024, 13:29 last edited by
            #4

            @JKSH

            class Outcome : public QObject
            {
                Q_OBJECT
                QML_ELEMENT
                ...
                Q_PROPERTY(ValveConfigurationList valveConfigurationList READ valveConfigurationList WRITE setValveConfigurationList NOTIFY valveConfigurationListChanged FINAL)
            

            And the instance I'm using is in a parent QML file:

            property var outcome: outcomeComponent.createObject(parent)
            
                Component {
                    id: outcomeComponent
                    Outcome {
                        id: newOutcome
                    }
                }
            
            J 1 Reply Last reply 27 Apr 2024, 14:57
            0
            • M mzimmers
              27 Apr 2024, 13:29

              @JKSH

              class Outcome : public QObject
              {
                  Q_OBJECT
                  QML_ELEMENT
                  ...
                  Q_PROPERTY(ValveConfigurationList valveConfigurationList READ valveConfigurationList WRITE setValveConfigurationList NOTIFY valveConfigurationListChanged FINAL)
              

              And the instance I'm using is in a parent QML file:

              property var outcome: outcomeComponent.createObject(parent)
              
                  Component {
                      id: outcomeComponent
                      Outcome {
                          id: newOutcome
                      }
                  }
              
              J Offline
              J Offline
              JKSH
              Moderators
              wrote on 27 Apr 2024, 14:57 last edited by
              #5

              @mzimmers said in bug in a JS function:

              And the instance I'm using is in a parent QML file:

              Make your variables fully-qualified (see https://forum.qt.io/topic/156292/how-to-order-object-creation/ ). That should also take care of your ReferenceError

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              M 1 Reply Last reply 28 Apr 2024, 01:31
              1
              • J JKSH
                27 Apr 2024, 14:57

                @mzimmers said in bug in a JS function:

                And the instance I'm using is in a parent QML file:

                Make your variables fully-qualified (see https://forum.qt.io/topic/156292/how-to-order-object-creation/ ). That should also take care of your ReferenceError

                M Offline
                M Offline
                mzimmers
                wrote on 28 Apr 2024, 01:31 last edited by
                #6

                @JKSH thanks for the suggestion. Unfortunately, I'm still having the same problem, except now it's equipmentEdit (see below) that's undefined.

                // EquipmentConfigEdit.qml
                ColumnLayout {
                    id: equipmentEdit
                    property var outcome: outcomeComponent.createObject(equipmentEdit) as Outcome
                
                    Component {
                        id: outcomeComponent
                        Outcome {
                            id: newOutcome
                        }
                    }
                

                Used here (I've removed most of the logs):

                function replaceValve(b, i) {
                    if (b === 2) { // and it is 2
                        var pumpUuid = equipmentEdit.equipmentCopy.uuid
                        var assignedValves = equipmentEdit.outcome.valveConfigurationList
                        var indexToReplace = assignedValves.indexOf(modelData)
                        var newValveUuid = unassignedValves[i]
                        assignedValves[indexToReplace] = newValveUuid
                        assignedValves.splice(indexToReplace, 1, newValveUuid)
                
                 // this line causes the trouble.
                        equipmentEdit.outcome.valveConfigurationList = assignedValves
                        
                        console.log("EquipmentSelectValves.qml.replaceValve(): equipmentEdit.outcome.valveConfigurationList is " + equipmentEdit.outcome.valveConfigurationList)
                

                All my logs suggest that everything is working...up to my assignment of the valve configuration list. I should point out that it isn't just outcome (or equipmentEdit) that is now undefined; it appears to be anything that comes after that statement.

                J 1 Reply Last reply 28 Apr 2024, 11:02
                0
                • M mzimmers
                  28 Apr 2024, 01:31

                  @JKSH thanks for the suggestion. Unfortunately, I'm still having the same problem, except now it's equipmentEdit (see below) that's undefined.

                  // EquipmentConfigEdit.qml
                  ColumnLayout {
                      id: equipmentEdit
                      property var outcome: outcomeComponent.createObject(equipmentEdit) as Outcome
                  
                      Component {
                          id: outcomeComponent
                          Outcome {
                              id: newOutcome
                          }
                      }
                  

                  Used here (I've removed most of the logs):

                  function replaceValve(b, i) {
                      if (b === 2) { // and it is 2
                          var pumpUuid = equipmentEdit.equipmentCopy.uuid
                          var assignedValves = equipmentEdit.outcome.valveConfigurationList
                          var indexToReplace = assignedValves.indexOf(modelData)
                          var newValveUuid = unassignedValves[i]
                          assignedValves[indexToReplace] = newValveUuid
                          assignedValves.splice(indexToReplace, 1, newValveUuid)
                  
                   // this line causes the trouble.
                          equipmentEdit.outcome.valveConfigurationList = assignedValves
                          
                          console.log("EquipmentSelectValves.qml.replaceValve(): equipmentEdit.outcome.valveConfigurationList is " + equipmentEdit.outcome.valveConfigurationList)
                  

                  All my logs suggest that everything is working...up to my assignment of the valve configuration list. I should point out that it isn't just outcome (or equipmentEdit) that is now undefined; it appears to be anything that comes after that statement.

                  J Offline
                  J Offline
                  JKSH
                  Moderators
                  wrote on 28 Apr 2024, 11:02 last edited by
                  #7

                  @mzimmers It's not clear from your snippets:

                  • Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?
                  • Where is `unassignedValves defined? What does it contain?
                  • What is the definition of ValveConfigurationList?

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  M 1 Reply Last reply 28 Apr 2024, 12:29
                  0
                  • J JKSH
                    28 Apr 2024, 11:02

                    @mzimmers It's not clear from your snippets:

                    • Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?
                    • Where is `unassignedValves defined? What does it contain?
                    • What is the definition of ValveConfigurationList?
                    M Offline
                    M Offline
                    mzimmers
                    wrote on 28 Apr 2024, 12:29 last edited by
                    #8

                    @JKSH said in bug in a JS function:

                    @mzimmers It's not clear from your snippets:

                    • Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?

                    No, it's in another QML file. EquipmentConfigEdit.qml has a DelegateChoice that uses VspEdit.qml, which uses another file with the above script.

                    • Where is `unassignedValves defined? What does it contain?

                    In EquipmentConfigEdit.qml (I forgot to qualify that one; now fixed). Here's the definition:

                    property var unassignedValves: outcomeModel.unassignedValves() 
                    
                    • What is the definition of ValveConfigurationList?
                    #define ValveConfigurationList QList<QUuid>
                    class Outcome: public QObject
                    {
                        Q_OBJECT
                        QML_ELEMENT
                        Q_PROPERTY(ValveConfigurationList valveConfigurationList READ valveConfigurationList WRITE setValveConfigurationList NOTIFY valveConfigurationListChanged FINAL)
                        ValveConfigurationList valveConfigurationList() { return m_valveConfigurationList; }
                        bool setValveConfigurationList(const ValveConfigurationList &list);
                    
                    J 1 Reply Last reply 28 Apr 2024, 13:08
                    0
                    • M mzimmers
                      28 Apr 2024, 12:29

                      @JKSH said in bug in a JS function:

                      @mzimmers It's not clear from your snippets:

                      • Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?

                      No, it's in another QML file. EquipmentConfigEdit.qml has a DelegateChoice that uses VspEdit.qml, which uses another file with the above script.

                      • Where is `unassignedValves defined? What does it contain?

                      In EquipmentConfigEdit.qml (I forgot to qualify that one; now fixed). Here's the definition:

                      property var unassignedValves: outcomeModel.unassignedValves() 
                      
                      • What is the definition of ValveConfigurationList?
                      #define ValveConfigurationList QList<QUuid>
                      class Outcome: public QObject
                      {
                          Q_OBJECT
                          QML_ELEMENT
                          Q_PROPERTY(ValveConfigurationList valveConfigurationList READ valveConfigurationList WRITE setValveConfigurationList NOTIFY valveConfigurationListChanged FINAL)
                          ValveConfigurationList valveConfigurationList() { return m_valveConfigurationList; }
                          bool setValveConfigurationList(const ValveConfigurationList &list);
                      
                      J Offline
                      J Offline
                      JKSH
                      Moderators
                      wrote on 28 Apr 2024, 13:08 last edited by
                      #9

                      @mzimmers said in bug in a JS function:

                      #define ValveConfigurationList QList<QUuid>
                      class Outcome: public QObject
                      {
                          Q_OBJECT
                          QML_ELEMENT
                          Q_PROPERTY(ValveConfigurationList valveConfigurationList READ valveConfigurationList WRITE setValveConfigurationList NOTIFY valveConfigurationListChanged FINAL)
                          ValveConfigurationList valveConfigurationList() { return m_valveConfigurationList; }
                          bool setValveConfigurationList(const ValveConfigurationList &list);
                      

                      Hmm... I'm not sure if the #define will play nicely with Qt's property system. https://doc.qt.io/qt-6/qtqml-cppintegration-exposecppattributes.html#exposing-properties says "Do not use typedef or using for Q_PROPERTY types as these will confuse moc). I'd imagine that the same goes for #define.

                      As a sanity check, put qDebug() << list; inside setValveConfigurationList(). Is your C++ function receiving the expected list?

                      Try replacing ValveConfigurationList with QList<QUuid> throughout your header. Does that make a difference? (If not, your best bet for quick troubleshooting is to provide a minimal, compilable example that triggers the issue)

                      • Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?

                      No, it's in another QML file. EquipmentConfigEdit.qml has a DelegateChoice that uses VspEdit.qml, which uses another file with the above script.

                      OK. And does VspEdit contain required property EquipmentConfigEdit equipmentEdit or similar? (Remember, use EquipmentConfigEdit instead of var)

                      • Where is `unassignedValves defined? What does it contain?

                      In EquipmentConfigEdit.qml (I forgot to qualify that one; now fixed). Here's the definition:

                      property var unassignedValves: outcomeModel.unassignedValves() 
                      

                      I don't think this is related to your issue, but do you need a separate property called EquipmentConfigEdit.unassignedValves? Could you just do let newValveUuid = equipmentEdit.outcomeModel.unassignedValves[i] or similar?

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      M 1 Reply Last reply 29 Apr 2024, 00:23
                      0
                      • J JKSH
                        28 Apr 2024, 13:08

                        @mzimmers said in bug in a JS function:

                        #define ValveConfigurationList QList<QUuid>
                        class Outcome: public QObject
                        {
                            Q_OBJECT
                            QML_ELEMENT
                            Q_PROPERTY(ValveConfigurationList valveConfigurationList READ valveConfigurationList WRITE setValveConfigurationList NOTIFY valveConfigurationListChanged FINAL)
                            ValveConfigurationList valveConfigurationList() { return m_valveConfigurationList; }
                            bool setValveConfigurationList(const ValveConfigurationList &list);
                        

                        Hmm... I'm not sure if the #define will play nicely with Qt's property system. https://doc.qt.io/qt-6/qtqml-cppintegration-exposecppattributes.html#exposing-properties says "Do not use typedef or using for Q_PROPERTY types as these will confuse moc). I'd imagine that the same goes for #define.

                        As a sanity check, put qDebug() << list; inside setValveConfigurationList(). Is your C++ function receiving the expected list?

                        Try replacing ValveConfigurationList with QList<QUuid> throughout your header. Does that make a difference? (If not, your best bet for quick troubleshooting is to provide a minimal, compilable example that triggers the issue)

                        • Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?

                        No, it's in another QML file. EquipmentConfigEdit.qml has a DelegateChoice that uses VspEdit.qml, which uses another file with the above script.

                        OK. And does VspEdit contain required property EquipmentConfigEdit equipmentEdit or similar? (Remember, use EquipmentConfigEdit instead of var)

                        • Where is `unassignedValves defined? What does it contain?

                        In EquipmentConfigEdit.qml (I forgot to qualify that one; now fixed). Here's the definition:

                        property var unassignedValves: outcomeModel.unassignedValves() 
                        

                        I don't think this is related to your issue, but do you need a separate property called EquipmentConfigEdit.unassignedValves? Could you just do let newValveUuid = equipmentEdit.outcomeModel.unassignedValves[i] or similar?

                        M Offline
                        M Offline
                        mzimmers
                        wrote on 29 Apr 2024, 00:23 last edited by
                        #10

                        @JKSH said in bug in a JS function:

                        Hmm... I'm not sure if the #define will play nicely with Qt's property system. https://doc.qt.io/qt-6/qtqml-cppintegration-exposecppattributes.html#exposing-properties says "Do not use typedef or using for Q_PROPERTY types as these will confuse moc). I'd imagine that the same goes for #define.
                        As a sanity check, put qDebug() << list; inside setValveConfigurationList(). Is your C++ function receiving the expected list?

                        I stepped into it in the debugger; it seems to be getting the correct list.

                        Try replacing ValveConfigurationList with QList<QUuid> throughout your header. Does that make a difference? (If not, your best bet for quick troubleshooting is to provide a minimal, compilable example that triggers the issue)

                        No, it doesn't.

                        Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?

                        No, it's in another QML file. EquipmentConfigEdit.qml has a DelegateChoice that uses VspEdit.qml, which uses another file with the above script.

                        OK. And does VspEdit contain required property EquipmentConfigEdit equipmentEdit or similar? (Remember, use EquipmentConfigEdit instead of var)

                        No. VspEdit is used within EquipmentConfigEdit.qml as folllows:

                        ListView {
                            model: equipmentCopy
                            delegate: DelegateChooser {
                                role: "category"
                                DelegateChoice {
                                    roleValue: NgaUI.CATEGORY_VSP
                                    delegate: VspEdit {
                                        equipment: equipmentEdit.equipment
                                        equipmentCopy: equipmentEdit.equipmentCopy
                        

                        equipmentEdit is the id assigned to EquipmentConfigEdit.qml.

                        Where is `unassignedValves defined? What does it contain?
                        Also in EquipmentConfigEdit.qml:

                        property var unassignedValves: outcomeModel.unassignedValves()
                        

                        I don't think this is related to your issue, but do you need a separate property called EquipmentConfigEdit.unassignedValves? Could you just do let newValveUuid = equipmentEdit.outcomeModel.unassignedValves[i] or similar?

                        I did this (no change in results):

                        var newValveUuid = outcomeModel.unassignedValves()[i]
                        

                        I will work on a minimal example. Thanks for the help.

                        M 1 Reply Last reply 29 Apr 2024, 17:25
                        0
                        • M mzimmers
                          29 Apr 2024, 00:23

                          @JKSH said in bug in a JS function:

                          Hmm... I'm not sure if the #define will play nicely with Qt's property system. https://doc.qt.io/qt-6/qtqml-cppintegration-exposecppattributes.html#exposing-properties says "Do not use typedef or using for Q_PROPERTY types as these will confuse moc). I'd imagine that the same goes for #define.
                          As a sanity check, put qDebug() << list; inside setValveConfigurationList(). Is your C++ function receiving the expected list?

                          I stepped into it in the debugger; it seems to be getting the correct list.

                          Try replacing ValveConfigurationList with QList<QUuid> throughout your header. Does that make a difference? (If not, your best bet for quick troubleshooting is to provide a minimal, compilable example that triggers the issue)

                          No, it doesn't.

                          Where is replaceValve() defined? Is it inside EquipmentConfigEdit.qml?

                          No, it's in another QML file. EquipmentConfigEdit.qml has a DelegateChoice that uses VspEdit.qml, which uses another file with the above script.

                          OK. And does VspEdit contain required property EquipmentConfigEdit equipmentEdit or similar? (Remember, use EquipmentConfigEdit instead of var)

                          No. VspEdit is used within EquipmentConfigEdit.qml as folllows:

                          ListView {
                              model: equipmentCopy
                              delegate: DelegateChooser {
                                  role: "category"
                                  DelegateChoice {
                                      roleValue: NgaUI.CATEGORY_VSP
                                      delegate: VspEdit {
                                          equipment: equipmentEdit.equipment
                                          equipmentCopy: equipmentEdit.equipmentCopy
                          

                          equipmentEdit is the id assigned to EquipmentConfigEdit.qml.

                          Where is `unassignedValves defined? What does it contain?
                          Also in EquipmentConfigEdit.qml:

                          property var unassignedValves: outcomeModel.unassignedValves()
                          

                          I don't think this is related to your issue, but do you need a separate property called EquipmentConfigEdit.unassignedValves? Could you just do let newValveUuid = equipmentEdit.outcomeModel.unassignedValves[i] or similar?

                          I did this (no change in results):

                          var newValveUuid = outcomeModel.unassignedValves()[i]
                          

                          I will work on a minimal example. Thanks for the help.

                          M Offline
                          M Offline
                          mzimmers
                          wrote on 29 Apr 2024, 17:25 last edited by
                          #11

                          First attempt at a minimal example produced a working script (crud).

                          I'm 99% sure that I'm successfully accessing the variables created in the file EquipmentConfigEdit.qml. Now, with the fully qualified variable names, I'm getting the same error, but on "equipmentEdit."

                          assignedValves[indexToReplace] = newValveUuid
                          console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves (after) is " + assignedValves)
                          
                          equipmentEdit.outcome.valveConfigurationList = assignedValves
                          // line 197 below.
                          console.log("EquipmentSelectValves.qml.replaceValve(): equipmentEdit.outcome.valveConfigurationList is " + equipmentEdit.outcome.valveConfigurationList)
                          

                          produces this error:

                          qrc:/qt/qml/NgaIcdFw/qml/equipment/EquipmentSelectValves.qml:197: ReferenceError: equipmentEdit is not defined
                          

                          if I comment out that log, the next variable I hit is said to be not defined.

                          It's really like the call to setValveConfigurationList() is somehow clobbering something in my script.

                          M 1 Reply Last reply 30 Apr 2024, 16:10
                          0
                          • M mzimmers
                            29 Apr 2024, 17:25

                            First attempt at a minimal example produced a working script (crud).

                            I'm 99% sure that I'm successfully accessing the variables created in the file EquipmentConfigEdit.qml. Now, with the fully qualified variable names, I'm getting the same error, but on "equipmentEdit."

                            assignedValves[indexToReplace] = newValveUuid
                            console.log("EquipmentSelectValves.qml.replaceValve(): assignedValves (after) is " + assignedValves)
                            
                            equipmentEdit.outcome.valveConfigurationList = assignedValves
                            // line 197 below.
                            console.log("EquipmentSelectValves.qml.replaceValve(): equipmentEdit.outcome.valveConfigurationList is " + equipmentEdit.outcome.valveConfigurationList)
                            

                            produces this error:

                            qrc:/qt/qml/NgaIcdFw/qml/equipment/EquipmentSelectValves.qml:197: ReferenceError: equipmentEdit is not defined
                            

                            if I comment out that log, the next variable I hit is said to be not defined.

                            It's really like the call to setValveConfigurationList() is somehow clobbering something in my script.

                            M Offline
                            M Offline
                            mzimmers
                            wrote on 30 Apr 2024, 16:10 last edited by
                            #12

                            @JKSH I have a minimal example now. I've zipped it up. Where would you like me to put it?

                            J 1 Reply Last reply 1 May 2024, 14:39
                            0
                            • M mzimmers
                              30 Apr 2024, 16:10

                              @JKSH I have a minimal example now. I've zipped it up. Where would you like me to put it?

                              J Offline
                              J Offline
                              JKSH
                              Moderators
                              wrote on 1 May 2024, 14:39 last edited by
                              #13

                              @mzimmers said in bug in a JS function:

                              @JKSH I have a minimal example now. I've zipped it up. Where would you like me to put it?

                              Any file sharing service of your choice should be fine (Dropbox, Google Drive, Microsoft OneDrive, etc.) Or you could push it to a public Git host (e.g. GitHub, Atlassian Bitbucket, etc.)

                              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                              M 1 Reply Last reply 1 May 2024, 15:47
                              0
                              • J JKSH
                                1 May 2024, 14:39

                                @mzimmers said in bug in a JS function:

                                @JKSH I have a minimal example now. I've zipped it up. Where would you like me to put it?

                                Any file sharing service of your choice should be fine (Dropbox, Google Drive, Microsoft OneDrive, etc.) Or you could push it to a public Git host (e.g. GitHub, Atlassian Bitbucket, etc.)

                                M Offline
                                M Offline
                                mzimmers
                                wrote on 1 May 2024, 15:47 last edited by
                                #14

                                @JKSH Here it is:

                                my zip zile

                                If you can figure out what's going on with this, I'll buy you a seafood dinner the next time you're in Monterey.

                                1 Reply Last reply
                                0
                                • J Offline
                                  J Offline
                                  JKSH
                                  Moderators
                                  wrote on 3 May 2024, 17:00 last edited by
                                  #15

                                  Looks like you've found an interesting bug related to Components accessing external IDs.

                                  Add pragma ComponentBehavior: Bound to the top of EquipmentSelectValves.qml (see https://doc.qt.io/qt-6/qtqml-documents-structure.html#componentbehavior ). This makes the QML engine a bit stricter though, so you need to also mark your delegate's modelData and index properties as required property (see the examples at https://doc.qt.io/qt-6/qtquick-modelviewsdata-modelview.html#models ). This is not necessarily a bad thing, as it enforces good practice.

                                  Note: After this, your example will no longer complain that outcome is not defined, but it will complain about equipmentModel because that is truly not defined anywhere in your example.

                                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                  M 1 Reply Last reply 3 May 2024, 18:43
                                  1
                                  • J JKSH
                                    3 May 2024, 17:00

                                    Looks like you've found an interesting bug related to Components accessing external IDs.

                                    Add pragma ComponentBehavior: Bound to the top of EquipmentSelectValves.qml (see https://doc.qt.io/qt-6/qtqml-documents-structure.html#componentbehavior ). This makes the QML engine a bit stricter though, so you need to also mark your delegate's modelData and index properties as required property (see the examples at https://doc.qt.io/qt-6/qtquick-modelviewsdata-modelview.html#models ). This is not necessarily a bad thing, as it enforces good practice.

                                    Note: After this, your example will no longer complain that outcome is not defined, but it will complain about equipmentModel because that is truly not defined anywhere in your example.

                                    M Offline
                                    M Offline
                                    mzimmers
                                    wrote on 3 May 2024, 18:43 last edited by mzimmers 5 Mar 2024, 18:50
                                    #16

                                    @JKSH said in bug in a JS function:

                                    Looks like you've found an interesting bug related to Components accessing external IDs.

                                    I love when things aren't (entirely) my fault.

                                    Add pragma ComponentBehavior: Bound to the top of EquipmentSelectValves.qml
                                    you need to also mark your delegate's modelData and index properties as required property

                                    Done and done.

                                    it will complain about equipmentModel because that is truly not defined anywhere in your example.

                                    Yeah, I forgot to remove that part (because it bombed before it got there). Shouldn't be a problem in my real app, where I have this line in main.cpp:

                                        engine.rootContext()->setContextProperty("equipmentModel", equipmentModel);
                                    

                                    Let me know when you're in town, and I'll buy you the best dinner Monterey can offer (which is pretty damn good, IMO).

                                    Should I report this bug, and if so, how should I characterize it?

                                    1 Reply Last reply
                                    0
                                    • M mzimmers has marked this topic as solved on 3 May 2024, 18:43
                                    • J Offline
                                      J Offline
                                      JKSH
                                      Moderators
                                      wrote on 5 May 2024, 15:53 last edited by JKSH 5 May 2024, 15:54
                                      #17

                                      Actually, I don't think it's a bug after all. Basically:

                                      1. Your replaceValve() function is a "member" of your delegate. (More precisely, replaceValve() exists within the context of your valveBox delegate, which is separate from the context of EquipmentSelectValves by default)
                                      2. That function modifies the ListView's model.
                                      3. Modifying the model caused your delegate (and its context) to be destroyed.
                                      4. Destroying the delegate's context invalidates the references inside replaceValve().

                                      Here is a minimal reproducer for your issue:

                                      //pragma ComponentBehavior: Bound
                                      import QtQuick
                                      import QtQuick.Controls.Basic
                                      
                                      Window {
                                          width: 800
                                          height: 600
                                          visible: true
                                      
                                          ListView {
                                              id: lv
                                              anchors.fill: parent
                                              model: 1
                                              delegate: Button {
                                                  text: "Click me"
                                      
                                                  onClicked: {
                                                      console.log("parent: " + parent)
                                                      console.log("lv: " + lv)
                                                      lv.model = 0
                                                      console.log("parent: " + parent)
                                                      console.log("lv: " + lv)
                                                  }
                                      
                                                  Component.onDestruction: console.log("Destroyed", this)
                                              }
                                          }
                                      }
                                      
                                      

                                      Output:

                                      qml: parent: QQuickItem(0x1257086c4a0)
                                      qml: lv: QQuickListView(0x12570653350)
                                      qml: Destroyed Button_QMLTYPE_1(0x12570653b30)
                                      qml: parent: null
                                      Main.qml:22: ReferenceError: lv is not defined
                                      

                                      pragma ComponentBehavior: Bound changes QML's behaviour and puts replaceValve() inside the same context as EquipmentSelectValves, so you get the outcome that you expect. Qt can't make
                                      this the default yet because it will break old user code. But https://doc.qt.io/qt-6/qtqml-documents-structure.html#componentbehavior does say "The default value of ComponentBehavior is Unbound.... In a future version of Qt the default will change to Bound."

                                      I haven't visited Monterey before, but I'll give you a buzz if I'm ever in town. That seafood sounds tempting ;-)

                                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                      1 Reply Last reply
                                      0

                                      1/17

                                      26 Apr 2024, 18:58

                                      • Login

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