Front-end of POSTing to local file storage

I’m sure this is a pretty basic question that isn’t entirely specific to Dreamfactory, but what techniques are expected to be used to send a create file / create folder request to the API that contains both the json parameters, and binary data?

I’m currently using the JS SDK and an HTML form, and although I can create empty files via a combination of url parameters attached to a POST action with a file input, the file itself is never uploaded. The live API docs say the body of the request should contain the file data when creating a single file - does this mean I should encode as base64 or similar and attach a {body: xxxxx} object to the request, ignoring the FileRequest schema? Is creating a folder from a zip only possible when loading a file from an existing online URL?

Hey,

Thanks for reaching out to the forum! This is currently an issue when path is passed into our system. I will update you on a fix around lunch time.

Thanks,

  • Mark

Hey,

Go ahead and grab the sdk that Jason just updated for you:

This should fix the file upload issue.

This isn’t backwards compatible in the sense that our sample calls to Stringify Response, not the Post/Put.

It’s now reversed and you’re able to just ask for response.data then stringify your Post/Put Object.

It’s all in the source for app.js

Thanks,

  • Mark

Hi Mark,

Thanks for the response - I think my issue is probably with my understanding more than a bug though.

It seems like the API docs say a file can be uploaded as the body of the POST request to the createFile/createFolder URLs. Unless I am reading it wrong and this interface is only to alert the DSP to files uploaded by some other means.

I think when I am uploading a file via a form it is attached as formdata rather than binary in the body of the request. I was wondering what the most common method used to upload files from a user to local storage via the API was. I assumed forms, as other approaches would require JS FileReader etc.

So far I have tried variations of both

var file = document.getElementById("file").files[0]; //from form
 window.df.apis.app.createFile({"container": "app", "file_path": "temp.zip", "body":file});

and

       <form id="form" name="form" action="http://api.example.com:80/rest/app/app/temp.zip?check_exist=false&app_name=app" method="post" enctype="application/zip">
            <input type="file" name="file" id="file">
            </form>

Hi,

My apologies for the delay. I’ve reached out to engineering but would like you to send me an email to mark@dreamfactory.com - that way we can work with you directly. Might as well take advantage of the free 30 days of support.

Looking forward to the email!

Thanks,

  • Mark

I managed to resolve the trouble I was having by duplicating the file upload in the admin area.

The below works as expected:

<form id="fileImportForm" method="POST" enctype="multipart/form-data" >
       <input id="fileInput" type="file" name="files" size="50">
    </form> 

script:

        $("#fileImportForm").attr("action","http://api.domain.com/rest" + "/files/storagename/"+filename + "/?" + "app_name=app&extract=true&check_exist=false");
        $("#fileImportForm").submit();

Hello,

We to are having the same problem. If we use the createFile API, a file gets created on the server but is an empty file. I think the problem is on how the body parameter is assembled. From the mobile device the most likely scenario is to use a file picker to pick the file then update the database and also create a file on the server. Are there any examples on how to format the body parameter of the createFile API properly?

Hi,

When creating a file using a POST within the Live API try the following… Notice to the right of the “body” field that there is a “model schema” option that can be chosen. When clicking on this (make sure the body field is empty), it will automatically copy over the schema template for you to use.

This is true with all of our POST requests, but in this particular case the model schema is:

{
  "name": "",
  "path": "",
  "content_type": "",
  "metadata": [
    ""
  ]
}

Fill this in as you want your file to be created. If you need a more specific example, please let me know and I’ll provide it for you.

Many thanks,

  • Mark

Hello Mark,

What should be placed on the other parameters:

container : Name of the container where the file exists.

This is confusing since I am trying to upload a file and this should not exist yet on the container

file_path: Path and name of the file to create.

Is this the container + filename?

Since for createFile these are the only required parameters, I would think that container parameter should be the destination container for the upload and file_path would be the source file_path+filename of the file we want to upload.

The wiki for CreateFile is still empty. It would be great if you can give us an example of the parameter setup plus body content given a destination container and the path of the local file file we want to upload.

Troy,

Hey, I tried to put a little something together for you here so that I can convey the idea of what’s going on behind the scenes.

By the way I’m using the Live API model schema and simply filling in the name for the container, folder, file, etc.

First there is the container-level object (sports)

"container": [
    {
  "name": "Sports",
  "path": "",
  "metadata": [
    ""
  ],

Folder Object

“folder”: [
    {
      “name”: “Baseball”,
      “path”: “”,
      “metadata”: [
        “”
      ],
      “folder”: [
        “FolderRequest”
      ],

File object is done in the same manner:

“file”: [
        {
          “name”: “braves.jpg”,
          “path”: “”,
          “content_type”: “image”,
          “metadata”: [
            “”
          ]
        }]

Hope that this helps a bit man, enjoy your weekend!

  • Mark

Hello Mark,

Sorry Mark for not getting this.

We have a file that can be retrieved at:

http://df.systemacorp.com/files/dormfinder/images/dorms/athena.jpg

We are trying to use the LIVE API gefFile()
container: dormfinder
file_path: images/dorms/athena.jpg

We are getting a 404 response with this:

The requested URL /rest/files/dormfinder/images/dorms/athena.jpg was not found on this server.

How should container and file_path be set in this scenario? Note: I am still on v.1.5.9

Troy

I was able to recreate your specific scenario and get proper results. This screenshot is from the online file storage:

[The image you are requesting does not exist or is no longer available]

And this is my successful GET on this image file:

[The image you are requesting does not exist or is no longer available]

So, I’ve been able to replicate your issue successfully - please send me an email to support@dreamfactory.com if you are still unable to get this working.

Thanks,

  • Mark

Adding dormfinder to the path_file still gives a 404. Could this be a v1.5.9 issue?
[The image you are requesting does not exist or is no longer available]

I think this is an issue with the Live API in 1.5.9
Let me look a little bit closer.

Replace your web/swagger with this :

https://github.com/dreamfactorysoftware/dsp-core/tree/master/web/swagger

Shouldn’t be any issues using 1.5.9 with this.

1 Like

Hello,

We moved over to v1.6.10 already. We do not have a problem with GetFile(). We are able to retrieve an image and show it on a mobile phone. The problem we have is with using CreateFile() to try to upload an image. In jQuery Mobile we use :file Selector to select the image we want to upload.

How should we fill up.

{

“name”: “”,
“path”: “”,
“content_type”: “”,
“metadata”: [
""
]
}

Do we just fill up name, path, content_type. Is my assumption correct?

name: name of file when uploaded to the service
path: path of file including filename of the file on the mobile phone
content_type: of file to upload

metadata: ? do I have to read the file and convert it to base64 and put the result in metadata?

A code example would be greatly appreciated.

We are currently able to upload an image using the FORM POST method above but the problem with this method is the response goes to response page that shows the name of the file and path, which we do not want.

You’ll basically want to use a FormData object, here’s info on doing so:

http://stackoverflow.com/questions/5392344/sending-multipart-formdata-with-jquery-ajax

Hello, I am looking for solution how to upload image jpeg from android (iPhone also) application to dreamfactory in binary format. But with current android sdk from dreamfactory I can only use function createFile with json parameter, where image data I have to convert to base64.
How can I do this directly in binary format ?

Thank you,

Post the file, and use these two request headers:
(“X-File-Name”, file.name);
(“Content-Type”, file.type);

Let me know if that causes any issues.

Hi,
In current version of Android SDK, I cann’t add headers in FilesAppi.createFile(…), so I created new function createFile in my derived class, where I add your two request header.
As I want it for image upload, I setup content type to ‘image/jpeg’ and body is byte array.
Here is code:

String contentType = "image/jpeg";
// query params
Map queryParams = new HashMap();
queryParams.put("check_exist", String.valueOf(check_exist));
// header pre upload binarneho suboru
Map headerParams = new HashMap();
headerParams.put("X-File-Name", file.getName());
headerParams.put("Content-Type", contentType);
byte[] body = FileUtils.readFileToByteArray(file);
String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, body, headerParams, contentType);

Response is ok, dsp create file on server, but content is textual not binary. Content is converted in base64 string by dsp.

I need programmatically upload binary file same way as I can do this with dsp file manager action “Upload File”. When I use this form action, image file on server is stored in binary format.

Thank you.