create-contentful-app icon indicating copy to clipboard operation
create-contentful-app copied to clipboard

Impossible to monitor file upload progress using sdk.cma.upload

Open brootle opened this issue 2 years ago • 1 comments

I currently have a problem that I have no way to monitor file upload when using sdk.cma.upload The only available methods are these

upload: {
    get(params: OptionalDefaults<GetSpaceParams & {
        uploadId: string;
    }>): Promise<any>;
    create(params: OptionalDefaults<GetSpaceParams>, data: {
        file: string | ArrayBuffer | Stream;
    }): Promise<any>;
    delete(params: OptionalDefaults<GetSpaceParams & {
        uploadId: string;
    }>): Promise<any>;
};

brootle avatar Feb 26 '24 13:02 brootle

I had to use API directly, the downside is that I need to get CMA token from the user for this to work. You can get CMA token from a user during your app installation for example. Contentful SDK doesn't have a method to get access token which it is using to sign all the requests.

  async function customUploadMethod(file, accessToken, spaceId, environmentId, onProgress) {
    // Define the URL for Contentful's upload API
    const uploadUrl = `https://upload.contentful.com/spaces/${spaceId}/uploads`;
  
    // Use XMLHttpRequest for upload to listen to progress events
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();
      xhr.open('POST', uploadUrl, true);
  
      // Set the Authorization header with the access token
      xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`);

      // Set the Content-Type header to application/octet-stream
      xhr.setRequestHeader('Content-Type', 'application/octet-stream');
  
      // Listen for progress events
      xhr.upload.onprogress = function(event) {
        if (event.lengthComputable) {
          let percentComplete = (event.loaded / event.total) * 100;
          let roundedPercentComplete = Math.round(percentComplete);
          console.log(`Upload progress: ${roundedPercentComplete}%`);
          onProgress(roundedPercentComplete); // Call the onProgress callback with the progress percentage
        }
      };
  
      // Handle the response
      xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
          // Parse the JSON response
          const response = JSON.parse(xhr.responseText);
          resolve(response);
        } else {
          reject(new Error('Upload failed with status: ' + xhr.status));
        }
      };
  
      // Handle network errors
      xhr.onerror = function() {
        reject(new Error('Network error occurred during upload'));
      };
  
      // Send the request with the file data directly
      xhr.send(file);
    });
  }

brootle avatar Feb 28 '24 07:02 brootle