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. [SOLVED] QNetworkReply and lambda -- strange behaviour

[SOLVED] QNetworkReply and lambda -- strange behaviour

Scheduled Pinned Locked Moved General and Desktop
9 Posts 4 Posters 4.6k 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.
  • V Offline
    V Offline
    vmkan
    wrote on last edited by
    #1

    Hi there!

    I'm trying to write a simple network function. Now it looks like that:

    @void NetworkManager::getClanInfoByTag(const QString &tag)
    {
    QNetworkRequest request = QNetworkRequest(QUrl(clanInfoUrl.arg(appId).arg(tag)));

    QNetworkReply* reply = m_manager->get(request);
    
    connect(reply, &QNetworkReply::finished, [this, reply]()
    {
        qDebug() << sender();
        qDebug() << reply->errorString();
        qDebug() << reply->readAll();
    
        emit clanInfoByTagCompleted(reply->readAll(),
                                    reply->error() == QNetworkReply::NoError);
    });
    
    reply->deleteLater();
    

    }@

    So, I'm simply trying to request data by some url and print it. I know, that QNetworkAccessManager is asynchronous, so I wrote lambda instead of separate slot...and it doesn't work. No data in output of program. However, if
    @reply->deleteLater()@

    is commented, then qDebug prints

    QObject(0x0)
    "Unknown error"
    some valid data

    m_manager is declared as QNetworkAccessManager* inside my NetworkManager class.

    What am I doing wrong?
    Should I write separate slot for that?
    Thanks to any help.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      You are calling deleteLater directly in getClanInfoByTag rather that in the lambda which means that at the next event loop iteration your reply will be deleted. deleteLater won't wait for the lambda to be called or the reply to finish.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • V Offline
        V Offline
        vmkan
        wrote on last edited by
        #3

        [quote author="SGaist" date="1420321593"]Hi,

        You are calling deleteLater directly in getClanInfoByTag rather that in the lambda which means that at the next event loop iteration your reply will be deleted. deleteLater won't wait for the lambda to be called or the reply to finish.[/quote]

        Thanks, that seemes interesting! But after I've tried it, the output looks like in second case:

        QObject(0×0)
        “Unknown error”
        some valid data

        So, the problem is still present.

        1 Reply Last reply
        0
        • T Offline
          T Offline
          t3685
          wrote on last edited by
          #4

          Shouldn't the third argument be a QObject? It looks like you only have three arguments.

          1 Reply Last reply
          0
          • C Offline
            C Offline
            ckakman
            wrote on last edited by
            #5

            Hi,

            What do you consider as a problem?

            If you consider that sender() returns a null pointer as a problem, according to the "documentation":http://doc.qt.io/qt-5/qobject.html#sender , it seems to be the expected behavior. sender() returns a valid pointer when called in a slot.

            By the way, since "reply" is captured in the lambda, you don't need sender(). You already have the sender of the signal, i.e. "reply".

            If you consider not receiving any data as a problem, than SGaist has already given the answer for that. You should put the reply->deleteLater() into the lambda. Otherwise you'll have a logical error by deleting the "reply" object before receiving any reply.

            As for the address of the "reply" object, replace the first line of the lambda as follows:
            @qDebug() << reply;@

            1 Reply Last reply
            0
            • C Offline
              C Offline
              ckakman
              wrote on last edited by
              #6

              Aha, there is another issue in your code: You are calling reply->readAll() twice. You should call it once and store the returned data in a variable and than you should use it twice:
              @
              ...
              QByteArray data = reply->readAll();
              qDebug() << data;
              emit clanInfoByTagCompleted(data, ...);
              ...
              @

              1 Reply Last reply
              0
              • V Offline
                V Offline
                vmkan
                wrote on last edited by
                #7

                [quote author="ckakman" date="1420325742"]Aha, there is another issue in your code: You are calling reply->readAll() twice. You should call it once and store the returned data in a variable and than you should use it twice:
                @
                ...
                QByteArray data = reply->readAll();
                qDebug() << data;
                emit clanInfoByTagCompleted(data, ...);
                ...
                @[/quote]

                No, that's just for debugging =)

                [quote author="ckakman" date="1420325513"]Hi,
                What do you consider as a problem?
                [/quote]

                The main problem here -- "Unknown error", while reply->readAll() gives me valid QByteArray =(

                [quote author="t3685" date="1420325393"]Shouldn't the third argument be a QObject? It looks like you only have three arguments.[/quote]

                Qt supports lambda functions as slot functions, and in that case, only 3 arguments will be provided. Otherwise, that code shouldn't be compiled =)

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  ckakman
                  wrote on last edited by
                  #8

                  Look at the QIODevice "source code":https://qt.gitorious.org/qt/qtbase/source/73a1e8c60d894701f34806cc4b847aa2814bf389:src/corelib/io/qiodevice.cpp :line 1618

                  If the error string is empty, "Unknown error" is returned. Apparently, you should call errorString() when error() returns something other than NoError. That makes sense.

                  1 Reply Last reply
                  0
                  • V Offline
                    V Offline
                    vmkan
                    wrote on last edited by
                    #9

                    [quote author="ckakman" date="1420329539"]Look at the QIODevice "source code":https://qt.gitorious.org/qt/qtbase/source/73a1e8c60d894701f34806cc4b847aa2814bf389:src/corelib/io/qiodevice.cpp :line 1618

                    If the error string is empty, "Unknown error" is returned. Apparently, you should call errorString() when error() returns something other than NoError. That makes sense.[/quote]

                    Oh, my fault. Thank you! Everything works fine.

                    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