What is the correct way to write a stringstream using TIdHTTP.Put()
in Delphi FireMonkey?
I have a PHP API (slim) like this:
// Update user
$app->put('/api/user/update/{id}', function(Request $request, Response $response){
$id = $request->getAttribute('id');
$username = $request->getParam('username');
$password = $request->getParam('password');
$nama = $request->getParam('nama');
$alamat = $request->getParam('alamat');
$jenis_kelamin = $request->getParam('jenis_kelamin');
$foto = $request->getParam('foto');
$sql = "UPDATE user SET
username = :username,
password = :password,
nama = :nama,
alamat = :alamat,
jenis_kelamin = :jenis_kelamin,
foto = :foto
WHERE id = $id";
try{
// Get DB Object
$db = new db();
// Connect
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':nama', $nama);
$stmt->bindParam(':alamat', $alamat);
$stmt->bindParam(':jenis_kelamin', $jenis_kelamin);
$stmt->bindParam(':foto', $foto);
$stmt->execute();
echo '{"notice": {"text": "Customer Updated"}';
} catch(PDOException $e){
echo '{"error": {"text": '.$e->getMessage().'}';
}
});
The procedure in Delphi for posting data via HTTP is like this:
procedure TForm3.updateexample;
var
lHTTP: TIdHTTP;
lParamList: TStringList;
stream : TStringStream;
mydata,json: string;
begin
json := 'username='+edtusername.Text+
'password='+edtpassword.Text+
'nama='+edtnama.Text+
'alamat='+edtalamat.Text+
'jenis_kelamin='+cbbjkel.Selected.Text+
'foto="'+edtalamat.text;
stream := TStringStream.Create(json,Tencoding.UTF8);
//create
lHTTP := TIdHTTP.Create(nil);
try
mydata := lHTTP.put
('http://myweblablalbalbala/api/user/update/'+id,stream);
if Pos('Customer Updated', mydata) > 0 then
begin
ShowMessage('Update Succes');
end
else
ShowMessage('update fail');
finally
lHTTP.Free;
lParamList.Free;
end;
end;
The code works, but after sending an update, the data changes from this (before the update):
{"id":"1","username":"iboy","password":"123456","nama":"ishak","alamat":"cikupa","jenis_kelamin":"l","foto":"iboy.jpg"}
to this (after the update):
{"id":"1","username":"","password":"","nama":"","alamat":"","jenis_kelamin":"","foto":""}
Can you help me? What is the correct way to post a stringstream via HTTP I Delphi?
You are not formatting your TStringstream
data correctly. It is not even close to being JSON (despite your variable name). And you are also not setting the TIdHTTP.Request.ContentType
property so the server knows what kind of data you are actually sending.
If you read the Slim documentation, Slim supports the following media types out of the box:
The data you are trying to send is closest to application/x-www-form-urlencoded
. That is normally sent using TIdHTTP.Post()
instead of TIdHTTP.Put()
, by giving it a TStrings
object of name=value
pairs. Post()
will format the values in the application/x-www-form-urlencoded
format for you, and set the Request.ContentType
property to match.
Your PHP
is expecting a PUT
request instead of a POST
request. Per the Slim documentation, you can actually send a POST
request and make it act like a PUT
request, by either:
including a _METHOD=PUT
value in your data (application/x-www-form-urlencoded
only)
including an X-HTTP-Method-Override: PUT
HTTP request header (works with any media type).
Try something more like this:
procedure TForm3.UpdateExample;
var
lHTTP: TIdHTTP;
lParamList: TStringList;
lReply: string;
begin
lParamList := TStringList.Create;
try
lParamList.Add('username='+edtusername.Text);
lParamList.Add('password='+edtpassword.Text);
lParamList.Add('nama='+edtnama.Text);
lParamList.Add('alamat='+edtalamat.Text);
lParamList.Add('jenis_kelamin='+cbbjkel.Selected.Text);
lParamList.Add('foto='+edtalamat.Text);
lHTTP := TIdHTTP.Create(nil);
try
// use one of these, not both!
lParamList.Add('_METHOD=PUT');
lHTTP.Request.MethodOverride := 'PUT';
lReply := lHTTP.Post('http://myweblablalbalbala/api/user/update/'+id, lParamList);
if Pos('Customer Updated', lReply) > 0 then
ShowMessage('Update Success')
else
ShowMessage('Update Fail');
finally
lHTTP.Free;
end;
finally
lParamList.Free;
end;
end;