PDA

View Full Version : WebService REST CPP-QML



RegMe
25th May 2016, 11:33
Hi Forum,

I have a problem, I want to get the response from the serveur if the operation is Ok or not, So I analysed
QNetworkRequest::HttpStatusCodeAttribute

// *** createProject( param ) ***


//Create project using post json
// ...
reply = manager->post(request, dataByteArray);
/* The finished() signal is triggered once an HTTP request is complete, by connect method we are connecting finished signal with the slot method onRequestFinished(user defined method). If it returns true it means connection is successful else not. You can process the response of the call in this user defined method */
result = connect(reply, SIGNAL(finished()), this, SLOT(onFinished()));

// *** slot onFinished() ***


bool Connection::onFinished()
{
codeResponse = false;
qDebug() << "QNetworkRequest::HttpStatusCodeAttribute" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute ).toInt() << "received";

if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute ).toInt() == 201)
{
codeResponse = true;
}
return codeResponse;
}

// *** getter ***

bool Connection::getResponse()
{
return codeResponse;
}


QML code

connection.createProject( param );
rep = connection.getResponse()
console.log("Response: "+rep)

infoAdd.open()


All is OK, but in QML sometimes function getResponse() runs before the slot onFinished() ??

So there is an other way whitout using getResponse() to get response from onFinichid() ?

I tried to use connection.onFinichid() in QML but it executed 2 times :
1st with connection.createProject( param ), 2nd directly connection.onFinichid() == > Response always = false

I try to find an easy way to get the resp without getter getResponse()

Cheers,

anda_skoa
25th May 2016, 12:32
If you call the method that initiates the HTTP post and immediately call the getter, then the post has not happend yet.

What you could do is add a signal to the Connection class and emit it in onFinished(), it could even have the code as its argument.

If the "connection" object in QML has been created in QML then you can use the usual onSignalname syntax, otherwise you can use a Connections element or connect a script function using connection.signalname.connect(functionname)

Cheers,
_

RegMe
25th May 2016, 18:33
Thanks, I still have the problem

// *** slot onFinished() ***

void Connection::onFinished()
{
bool codeResponse = false;
qDebug() << "QNetworkRequest::HttpStatusCodeAttribute" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute ).toInt() << "received";

if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute ).toInt() == 201)
{
codeResponse = true;
}

emit finishChanged(codeResponse);

}

QML code
Connection{
id: connection
onFinishChanged: {
console.log("Received : " + codeResponse)
updateOK = codeResponse
}
}

QML code : createProject
connection.createProject( param );

infoUpdate.open()


MessageDialog{
id:infoUpdate

icon: StandardIcon.Information
text: updateOK == true ? "UPDATE OK":"ERROR UPDATING !!"
onAccepted: {

updateOK = false

updateWindow.close()
}
}

Result out : ERROR UPDATING !!

I still have the probleme of synchronisation: infoUpdate runs before the end of the Slot onFinished()

anda_skoa
30th May 2016, 18:16
Yes, you still call infoUpdate.open() right after you queue the request.
If you don't give your program any chance to actually perform the request, then it can't.

Just consider a real live situation with asynchronous delivers: ordering food in a restaurant

1) you give the waiter your order
2) you immediately try to start eating?

No, that won't work, as the waiter hadn't had time to bring your order to the kitchen, the cook didn't have time to prepare what you've asked for, so the waiter couldn't have brought it back yet

What you really do is

1) you give your order to the waiter
2) you wait until the waiter returns with your meal
3) you eat

In your code the waiter is the HTTP call, the kitchen is the REST server.
You can only start eating (processing the data), once the waiter has returned.

Cheers,
_

RegMe
31st May 2016, 10:53
Hiii,

It has been a long time ;) I called infoUpdate.open() inside :


Connection{
id: connection
onFinishChanged: {
console.log("Received : " + codeResponse)
updateOK = codeResponse
infoUpdate.open()
}
}


I think that you mean this method ??

What happed to qtcentre !: off for a week !!!

anda_skoa
31st May 2016, 11:54
Yes, that's what I meant.

Cheers,
_