Upload KML file programmatically

2401
2
Jump to solution
10-08-2017 12:32 PM
OnoCrack
New Contributor

Hi,

I'm trying to use the arcgis rest api to upload kml file to the portal. I made addItem request and then addPart request to upload the file itself. The documentation does not mention how to send the file, so I read the content of the file as text and send it but I'm getting Internal Server Error response.

Here is my code (I also added the js file as attachment):

// get list of files
var files = this.fileSelect.files;

// continue only if the user select one (or more) files
if (files.length > 0) {
   this.uploadButton.innerHTML = "Uploading..";

   var file = files[0];

   fetch('https://www.arcgis.com/sharing/rest/content/users/*****/addItem', {
      method: 'post',
      headers: {
         'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
      },
      body: 'token='+encodeURIComponent(token)+'&f=json&title='+encodeURIComponent(file.name)+'&type=KML&filename='+encodeURIComponent(file.name)+'&multipart='+encodeURIComponent(true)
   })
   .then(res => res.json())
   .then(res => {
      return new Promise(resolve => {
         var id = res.id;

         var fileReader = new FileReader();

         // when finish to read the file, make request with the content of the file
         fileReader.onload = (e) => {
            let data = e.target.result;

            fetch('https://www.arcgis.com/sharing/rest/content/users/****/items/'+id+'/addPart', {
               method: 'post',
               headers: {
                  'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
               },
               body: 'token='+token+'&f=json&partNum=1&file='+encodeURIComponent(data)
            })
            .then(res => resolve(res));
         }

         // read file content
         fileReader.readAsText(file);
      });
   })
   .then(res => res.json())
   .then(res => {
      console.log(res); // THIS LINE LOGS "500 - INTERNAL SERVER ERROR..."
      if (res.success) {
         return fetch('https://www.arcgis.com/sharing/rest/content/users/*****/items/'+id+'/commit', {
            method: 'post',
         });
      } else {
         return null; // ...THEN GOES HERE
      }
   })
   .then(res => {
      if (res) {
         return res.json();
      } else {
         return undefined; // ...AND THEN RETURN UNDEFINED!
      }
   })
   .then(res => {
      console.log(res);
   });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Could someone please explain how to upload small file (kml, less than 5mb) to the portal using arcgis rest api (javascript)?

Thank you!

p.s sorry if I have grammar mistakes (I'm not native english speaker) ..

1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

In my experience the best way to approach this is to manually add the KML as a portal item using the Add Item option from My Contents and use your browser's dev tools to look at the request that gets sent (chrome has a preserve log option to make sure the network log keeps the request).  You can use this request as a template for what your request has to do.

That aside, here's some code I've used to upload to upload files as portal items using esri/request:

// user is a portalUser.
// fileList is an array of files.
// tags is an array of strings
function addFileaAsPortalItem(user, fileList, tags){
  const file = fileList[0];
  let form = new FormData();
  form.append('file',file);
  form.append("f", "json");
  form.append("title", file.name);
  form.append("name", file.name);
  form.append("type",'KML');
  form.append("token", <server token>);
  form.append("filename", file.name);
  form.append("tags", tags.join());

  return esriRequest(`${user.userContentUrl}/addItem`,{
    method: 'post',
    query: form
  });
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I'm not sure if this will fail when the file is too large.  I've used it to upload images, kml, text documents, and more.  It also may be a good idea to use esri/request for this, as opposed to the fetch api.

View solution in original post

2 Replies
ThomasSolow
Occasional Contributor III

In my experience the best way to approach this is to manually add the KML as a portal item using the Add Item option from My Contents and use your browser's dev tools to look at the request that gets sent (chrome has a preserve log option to make sure the network log keeps the request).  You can use this request as a template for what your request has to do.

That aside, here's some code I've used to upload to upload files as portal items using esri/request:

// user is a portalUser.
// fileList is an array of files.
// tags is an array of strings
function addFileaAsPortalItem(user, fileList, tags){
  const file = fileList[0];
  let form = new FormData();
  form.append('file',file);
  form.append("f", "json");
  form.append("title", file.name);
  form.append("name", file.name);
  form.append("type",'KML');
  form.append("token", <server token>);
  form.append("filename", file.name);
  form.append("tags", tags.join());

  return esriRequest(`${user.userContentUrl}/addItem`,{
    method: 'post',
    query: form
  });
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I'm not sure if this will fail when the file is too large.  I've used it to upload images, kml, text documents, and more.  It also may be a good idea to use esri/request for this, as opposed to the fetch api.

OnoCrack
New Contributor

That's working. Thanks!