Jump to content

Upload Image to Rest Server


Recommended Posts

Hello,

 

I want to upload an image to my rest server, where it is stored as BLOB in my database.

 

I use the REST[...].Call.Put() function and my image is already in a JFile (JBlob) variable. But I don't know how to convert that data in order to send it properly?

e.g. Send it as byte array or convert it to a base64 string.

 

When I convert it, eg. to an UInt8Array, and pass that data in the put method I get the following error:

 

Uncaught InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.  [line #5928]

  call := REST[FRootURL, PrepareURI(aDestURI)].Call;

  fileReader := JFileReader.Create;
  fileReader.onload :=
    function(event: JEvent): Variant
    begin
      var data: JUint8Array := JUint8Array.Create(JTypedArray(Variant(event.target).result));

      writeln(data.length.tostring);

      call.Put(data);
      result := true;
    end;

  fileReader.readAsArrayBuffer(aBlob);
Link to post
Share on other sites

The Put method comes in two versions:

 

    function Put(data: string = ''): TRESTCall; overload;
    function Put(data: JObject): TRESTCall; overload;
 
You should be able to do
 
call.Put(JObject(data));
 
but i have not checked if it works.
 
The error message above seems related to something else.
 
Either headers are set too early or too late, i can't know by the error message (without research).
 
Too early (perhaps not your problem): It [the error] would be emitted during the execution of "Call" (in TRESTCall.Create TW3HttpHeader.SetRequestHeader is called). The Underlying XHTTPRequest object should be in an ok state by then (have not checked, when i think about it i have never used the header functionality like that).
Did you make sure there's no requests in the cache that may have header info?
 
Too late (and i think this may be your problem): In the string version of Put Primoz inserts a header to tell the server this is text data. Then stringifies your JObject. So casting won't help in your original quest. You could perhaps try to stringify yourself or set that header early on (['Content-Type'] := 'application/json' if needed).
 
call.Put(JSON.stringify(data));
 
HTH,
 
/Dany
Link to post
Share on other sites

Thanks Dany.

 

I got it work. I had to use FileReader.readAsBinaryString (which is currently not exposed by the wrapper) and encoded it to base64. Then on REST server I decoded the string and converted it into a stream.

 

Here is the code, if someone has a similary issue:

  fileReader := JFileReaderHelper.Create;
  fileReader.onload :=
    function(event: JEvent): Variant
    begin
      var data: string := VarToStr(Variant(event.target).result);

      data := Base64Encoder.Encode(data);

      call.Put(data);
      result := true;
    end;

  fileReader.readAsBinaryString(aBlob);

regarding the error: There is an issue in the RTL. It tries to set an header, before the FHttp object is opend.

function TRESTCall.PUT(data: JObject): TRESTCall;
begin
  FHttp.RequestHeaders['Content-Type'] := 'application/json'; //Throws exception: FHttp must first be opened!
  Result := Send('PUT', JSON.Stringify(data));
end;
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...