1 Reply Latest reply on Jul 25, 2014 1:07 PM by Robert Hanson

    Upload a File To Jive From Within an App?


      I'm developing an application in the Jive App Framework that lets users upload multiple files to Jive at once from their local file system (with the same tags, into the same Place, etc.).  However, I've been having trouble using the API to accomplish this.  Is this possible with the Jive JavaScript API, or does that API only let you upload files from publicly available URLs?  I know that you can accomplish this via the REST API and multi-part form requests (see Upload file directly(not from url)), as I've done it before via a Python script.  However, I have not been able to get this to work from within an App.


      An example of steps I've taken is:


      1. Read the user's file using JavaScript's FileReader interface.
      2. Read the data as a base64 string.
      3. Embed the base64 string in a multi-part form request.
      4. Using the Jive Connects API to connect to our Jive instance and access the REST API (need the Connects API due to cross-site restrictions)
      5. Send a POST request to /contents with the multi-part form as the "body" parameter of the Jive Connects JSON.


      The content item is successfully created, but the file ends up being corrupted.  In addition to reading the file as a base64 string, I've also tried reading the file as an ArrayBuffer and then converting to both UTF-8 and ASCII strings.  Nothing seems to work, however.


      Ryan Rutan, do you know if there's something I'm missing here?  I'd hate to have to upload the file to our custom server before uploading it to Jive to ensure proper encoding, but that's exactly what we're doing now until we can find a way to upload it directly to Jive without corrupting the file.


      Thank you very much for your help!

        • Re: Upload a File To Jive From Within an App?
          Robert Hanson

          This is some AngularJS code that I am using to do this.  You should be able to replace the $http.post with the equivalent jQuery code if needed.


          this.storeJSON = function (pageUrl, name, data, callback) {
              var fd = new FormData();
              var blobData = new Blob([JSON.stringify(data)], {type : 'text/plain'});
              fd.append('file', blobData, name);
              $http.post(pageUrl, fd, {
                 transformRequest: angular.identity,
                 headers: {'Content-Type': undefined}
              .success(function(){ callback(true); })
              .error(function(){ callback(false); });


          The key is using FormData and Blob, both of which are part of the file-api that is supported by modern browsers (IE10+, Firefox, Chrome, Safari).


          Here are the params:

          pageUrl: The REST url for the attachments on a page, eg. "/api/core/v3/attachments/contents/1014"

          name: The name of the file to upload.

          data: In my case this is JSON data, but it can be anything.

          callback: Function that is called with the result of the upload.


          I assume that you are already using the file-api to get the list of files being uploaded in the browser.  If you are, you should already have a File object.  You would just send that to the server instead of the Blob.


          To get this to work I did have to set the system property jive.rest.internal.csrf.token.enabled to false.  There is a way to fix this, but I'm still working on implementing it.