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. JS Async Function in QML
Forum Updated to NodeBB v4.3 + New Features

JS Async Function in QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 4 Posters 11.0k 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.
  • Bernard RouhiB Offline
    Bernard RouhiB Offline
    Bernard Rouhi
    wrote on last edited by
    #1

    I'm wondering if it is possible to use an async function in QML.
    Like this:

    async function additem(clientName){
        myListModel.append({name:clientName});
    }
    

    Instead of using this:

    function additem(clientName){
        myListModel.append({name:clientName});
    }
    

    I've tried it and I get a syntax error: Expected token :'` and couldn't find any documentation about QML supporting JavaScript "async function".
    any idea why is that? or probably if there is any other way to do async in JS which can be used in QML?

    Note: I want to append data to my ListModel and I want to see it as its progress and I don't want whole application freeze until whole data appended to the model.

    Appreciate your time.

    raven-worxR 1 Reply Last reply
    0
    • Bernard RouhiB Bernard Rouhi

      I'm wondering if it is possible to use an async function in QML.
      Like this:

      async function additem(clientName){
          myListModel.append({name:clientName});
      }
      

      Instead of using this:

      function additem(clientName){
          myListModel.append({name:clientName});
      }
      

      I've tried it and I get a syntax error: Expected token :'` and couldn't find any documentation about QML supporting JavaScript "async function".
      any idea why is that? or probably if there is any other way to do async in JS which can be used in QML?

      Note: I want to append data to my ListModel and I want to see it as its progress and I don't want whole application freeze until whole data appended to the model.

      Appreciate your time.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @Bernard-Rouhi said in JS Async Function in QML:

      I don't want whole application freeze until whole data appended to the model

      when your whole application freezes by just appending a single value to the model you must have done something wrong in your implementation.
      Even when you make this function asyncronous the application would freeze once it gets added anyway.
      So whats the actual problem by calling the method directly?

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      Bernard RouhiB 1 Reply Last reply
      0
      • ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on last edited by
        #3

        Hi,
        you can't write 'async function' in qml.
        What you need is QML "workerScript" to do your list initialisation in separated thread.

        WorkerScript doc : http://doc.qt.io/qt-4.8/qml-workerscript.html

        LA

        Bernard RouhiB 1 Reply Last reply
        1
        • raven-worxR raven-worx

          @Bernard-Rouhi said in JS Async Function in QML:

          I don't want whole application freeze until whole data appended to the model

          when your whole application freezes by just appending a single value to the model you must have done something wrong in your implementation.
          Even when you make this function asyncronous the application would freeze once it gets added anyway.
          So whats the actual problem by calling the method directly?

          Bernard RouhiB Offline
          Bernard RouhiB Offline
          Bernard Rouhi
          wrote on last edited by
          #4

          @raven-worx said in JS Async Function in QML:

          @Bernard-Rouhi said in JS Async Function in QML:

          I don't want whole application freeze until whole data appended to the model

          when your whole application freezes by just appending a single value to the model you must have done something wrong in your implementation.
          Even when you make this function asyncronous the application would freeze once it gets added anyway.
          So whats the actual problem by calling the method directly?

          Thank you for the reply,
          okay, I have a ListView

          ListView {
              id: myList
              anchors.fill: parent
              model: myList
              delegate: myDelegate
          }
          

          and in my ListModel I have ListElement that contain an Array, and that Array contains multiple ListElement, one of the data is something like this:

          ListModel
          {
              id: myList
              ListElement{
                  name: "Bernard"
                  card: 100256
                  books:[
                      {value:"025684"},
                      {value:"568956"},
                      {value:"879256"},
                      {value:"125793"},
                      {value:"486257"}]
              }
          }
          

          you might wonder why list of ListElement for books, well, it's because ListElement and ListModel doesn't support simple Array (it's not documented if any), they only mentioned string and integer. so I have to use ListElement in such way.
          however, next I want to add the books to my ComboBox's model which is under Delegate:

          Component {
              id: myDelegate
              Rectangle
                  {
                   id: rowID
                   width: 300
                   height: 40
                   color: "#323232"
                   border.color: "white"
                   Row
                   {
                       anchors.fill: parent
                       anchors.leftMargin: 10
                       anchors.rightMargin: 10
                       Text{
                           id: nameID
                           text: name
                           font.pixelSize: 12
                           width: 50
                           wrapMode: Text.WrapAnywhere
                           color: "white"
                       }
          
                       Text{
                           text: "out:"
                           font.pixelSize: 12
                           color: "white"
                       }
          
                       ComboBox{
                           id: booksID
                           height: 20
                           width: 50
                           model: books
                       }
                   }
              }
          }
          

          as you can see I'm feeding the name to Text (id: nameID) but I want to add the books to ComboBox model (id: booksID) too, which it doesn't do it.

          so the easiest way that I figured out is by adding onCompleted to ComboBox under Delegate and handling it like so:

          ComboBox{
              id: booksID
              height: 20
              width: 50
              model: []
              Component.onCompleted:{
                  booksID.model = update_books(books);
                  function update_books(data)
                  {
                      var booksArray = Array();
                      for (var n=0; n < data.count ;n++){
                          booksArray.push(data.get(n).value);
                      }
                      return booksArray;
                  }
              }
          }
          

          well, I know I shouldn't do that in Delegate, cause Delegate doesn't keep them and it should be done in Model, but I couldn't find a way to feed the books to ComboBox's model and I thought of doing async function to keep the performance, but not document regarding that too.

          Hope that is clear my intention of using Async Function, but feel free to correct me if you find any process that I'm doing wrong, thanks for your time.

          W 1 Reply Last reply
          0
          • ODБOïO ODБOï

            Hi,
            you can't write 'async function' in qml.
            What you need is QML "workerScript" to do your list initialisation in separated thread.

            WorkerScript doc : http://doc.qt.io/qt-4.8/qml-workerscript.html

            LA

            Bernard RouhiB Offline
            Bernard RouhiB Offline
            Bernard Rouhi
            wrote on last edited by
            #5

            @LeLev said in JS Async Function in QML:

            Hi,
            you can't write 'async function' in qml.
            What you need is QML "workerScript" to do your list initialisation in separated thread.

            WorkerScript doc : http://doc.qt.io/qt-4.8/qml-workerscript.html

            LA

            Hi @LeLev

            Thanks for the reply, yeah, I try using that, but since it separates itself from QML Libraries and I need ListView's id to append ListElement to it, it doesn't look alike workable in my case.
            Please look at my reply to Raven-worx question, I did explain why I need the async function. hope that gives a clear idea of my question.

            1 Reply Last reply
            0
            • ODБOïO Offline
              ODБOïO Offline
              ODБOï
              wrote on last edited by
              #6

              Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

              I hope it helps you.
              LA

              Bernard RouhiB 2 Replies Last reply
              1
              • Bernard RouhiB Bernard Rouhi

                @raven-worx said in JS Async Function in QML:

                @Bernard-Rouhi said in JS Async Function in QML:

                I don't want whole application freeze until whole data appended to the model

                when your whole application freezes by just appending a single value to the model you must have done something wrong in your implementation.
                Even when you make this function asyncronous the application would freeze once it gets added anyway.
                So whats the actual problem by calling the method directly?

                Thank you for the reply,
                okay, I have a ListView

                ListView {
                    id: myList
                    anchors.fill: parent
                    model: myList
                    delegate: myDelegate
                }
                

                and in my ListModel I have ListElement that contain an Array, and that Array contains multiple ListElement, one of the data is something like this:

                ListModel
                {
                    id: myList
                    ListElement{
                        name: "Bernard"
                        card: 100256
                        books:[
                            {value:"025684"},
                            {value:"568956"},
                            {value:"879256"},
                            {value:"125793"},
                            {value:"486257"}]
                    }
                }
                

                you might wonder why list of ListElement for books, well, it's because ListElement and ListModel doesn't support simple Array (it's not documented if any), they only mentioned string and integer. so I have to use ListElement in such way.
                however, next I want to add the books to my ComboBox's model which is under Delegate:

                Component {
                    id: myDelegate
                    Rectangle
                        {
                         id: rowID
                         width: 300
                         height: 40
                         color: "#323232"
                         border.color: "white"
                         Row
                         {
                             anchors.fill: parent
                             anchors.leftMargin: 10
                             anchors.rightMargin: 10
                             Text{
                                 id: nameID
                                 text: name
                                 font.pixelSize: 12
                                 width: 50
                                 wrapMode: Text.WrapAnywhere
                                 color: "white"
                             }
                
                             Text{
                                 text: "out:"
                                 font.pixelSize: 12
                                 color: "white"
                             }
                
                             ComboBox{
                                 id: booksID
                                 height: 20
                                 width: 50
                                 model: books
                             }
                         }
                    }
                }
                

                as you can see I'm feeding the name to Text (id: nameID) but I want to add the books to ComboBox model (id: booksID) too, which it doesn't do it.

                so the easiest way that I figured out is by adding onCompleted to ComboBox under Delegate and handling it like so:

                ComboBox{
                    id: booksID
                    height: 20
                    width: 50
                    model: []
                    Component.onCompleted:{
                        booksID.model = update_books(books);
                        function update_books(data)
                        {
                            var booksArray = Array();
                            for (var n=0; n < data.count ;n++){
                                booksArray.push(data.get(n).value);
                            }
                            return booksArray;
                        }
                    }
                }
                

                well, I know I shouldn't do that in Delegate, cause Delegate doesn't keep them and it should be done in Model, but I couldn't find a way to feed the books to ComboBox's model and I thought of doing async function to keep the performance, but not document regarding that too.

                Hope that is clear my intention of using Async Function, but feel free to correct me if you find any process that I'm doing wrong, thanks for your time.

                W Offline
                W Offline
                wpurvis
                wrote on last edited by
                #7

                @Bernard-Rouhi I believe you should be able to assign the books to the ComboBox model using modelData.

                Like so:

                ComboBox{
                id: booksID
                model: modelData.books
                }

                Also, you can use a plain JavaScript array for a model. Works fine. That's all I ever use, for all my models — arrays of strings, arrays of objects, etc.

                Bernard RouhiB 1 Reply Last reply
                0
                • ODБOïO ODБOï

                  Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

                  I hope it helps you.
                  LA

                  Bernard RouhiB Offline
                  Bernard RouhiB Offline
                  Bernard Rouhi
                  wrote on last edited by
                  #8

                  @LeLev said in JS Async Function in QML:

                  Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

                  I hope it helps you.
                  LA

                  Thanks for the reply, I found a solution by adding textRole to ComBox like so:

                  ComboBox{
                      id: booksID
                      height: 20
                      width: 50
                      model: books
                      textRole: "value"
                  }
                  

                  but still, I'm looking for asyncing my javascript function, I could think of an existing similar idea called Ajax for web development in Restful API, but I want to do the same thing in QML with javascript functions.

                  1 Reply Last reply
                  0
                  • W wpurvis

                    @Bernard-Rouhi I believe you should be able to assign the books to the ComboBox model using modelData.

                    Like so:

                    ComboBox{
                    id: booksID
                    model: modelData.books
                    }

                    Also, you can use a plain JavaScript array for a model. Works fine. That's all I ever use, for all my models — arrays of strings, arrays of objects, etc.

                    Bernard RouhiB Offline
                    Bernard RouhiB Offline
                    Bernard Rouhi
                    wrote on last edited by
                    #9

                    @wpurvis said in JS Async Function in QML:

                    @Bernard-Rouhi I believe you should be able to assign the books to the ComboBox model using modelData.

                    Like so:

                    ComboBox{
                    id: booksID
                    model: modelData.books
                    }

                    Also, you can use a plain JavaScript array for a model. Works fine. That's all I ever use, for all my models — arrays of strings, arrays of objects, etc.

                    Hi @wpurvis , thanks for the reply, I didn't get the modelData, you mean ListModel id?
                    also again I'm looking for a way to async my javascript functions, something similar to Ajax in Restful API but in QML without Restful API of course.

                    W 1 Reply Last reply
                    0
                    • ODБOïO ODБOï

                      Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

                      I hope it helps you.
                      LA

                      Bernard RouhiB Offline
                      Bernard RouhiB Offline
                      Bernard Rouhi
                      wrote on last edited by
                      #10

                      @LeLev said in JS Async Function in QML:

                      Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

                      I hope it helps you.
                      LA

                      Hi @LeLev , thanks for the reply, yeah, I think the solution is to handle it on multi threads, I didn't get it at first but now I go through the documentations that make lots of sense.

                      1 Reply Last reply
                      1
                      • Bernard RouhiB Bernard Rouhi

                        @wpurvis said in JS Async Function in QML:

                        @Bernard-Rouhi I believe you should be able to assign the books to the ComboBox model using modelData.

                        Like so:

                        ComboBox{
                        id: booksID
                        model: modelData.books
                        }

                        Also, you can use a plain JavaScript array for a model. Works fine. That's all I ever use, for all my models — arrays of strings, arrays of objects, etc.

                        Hi @wpurvis , thanks for the reply, I didn't get the modelData, you mean ListModel id?
                        also again I'm looking for a way to async my javascript functions, something similar to Ajax in Restful API but in QML without Restful API of course.

                        W Offline
                        W Offline
                        wpurvis
                        wrote on last edited by
                        #11

                        @Bernard-Rouhi said in JS Async Function in QML:

                        I didn't get the modelData, you mean ListModel id?

                        No, I mean modelData, as described here.
                        It's an alternative way for the delegate to refer to its model data, i.e., an alternative to using named roles.
                        E.g., in your example, your delegate could refer to modelData.name, modelData.card, etc., and you should be able to set the ComboBox model to modelData.books. That's assuming you wanted to just use a plain JavaScript array of book values, rather than creating a bunch of ListElement entries.

                        1 Reply Last reply
                        0

                        • Login

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