Expand my Community achievements bar.

Applications for the 2024-2025 Adobe Experience Manager Champion Program are open!

AEM-User generated collections-dowload

Avatar

Level 2

Hello, AEM community.

We have a requirement to download the dam user-generated collection. As part of it, we read all collection items into an array and iterate through them using the code below. It sometimes works, but for huge files or files longer than 4-5 files, there is a problem with the last or first file.

 

if (!!collectionPath) {

        const collectionItemsArr = collectionPath.split(';'); // Split paths by ';'
        console.log("collectionItemsArr::",collectionItemsArr);
        if (collectionItemsArr.length > 0) {
            const filename = collectionTitle;
            let url = collectionItemsArr[0] + ".assetdownload.zip/" + encodeURIComponent(filename);
 const promises = [];
        if (collectionItemsArr.length > 1) {
    for (let i = 0; i < collectionItemsArr.length; i++) {
        collectionItemsArr[i] = collectionItemsArr[i];
    }
     url = addParameter(url, "path", collectionItemsArr);
}
            url = addParameter(url, "_charset_", "utf-8");
            url = addParameter(url, "licenseCheck", "true");
            url = addParameter(url, "flatStructure", "true");
            window.localStorage.removeItem("nonLicensedAssetPaths");
                  promises.push(downloadFile(url));
                    try {
                     // Wait for all downloads to complete
                     await Promise.all(promises);
                    } catch (error) {
                     console.error('Error downloading files:', error);
                    }
        }

const downloadFile = (url) => {
        return new Promise((resolve, reject) => {
            const downloadWindow = window.open(url, "_blank");
            if (downloadWindow) {
                // Resolve the promise when the download is complete
                downloadWindow.onload = () => {
                    resolve();
                };
            } else {
                reject(new Error("Failed to open download window"));
            }
        });
    };
function addParameter(url, paramName, paramValue) {
    if (paramValue && paramValue instanceof Array) {
        for (let i = 0; i < paramValue.length; i++) {
            url = addParameter(url, paramName, paramValue[i]);
        }
        return url;
    }

    const separator = url.indexOf("?") == -1 ? "?" : "&";
    const hashIdx = url.indexOf("#");
    if (hashIdx < 0) {
        return url + separator + encodeURIComponent(paramName) + "=" + encodeURIComponent(paramValue);
    } else {
        const hash = url.substring(hashIdx);
        url = url.substring(0, hashIdx);
        return url + separator + encodeURIComponent(paramName) + "=" + encodeURIComponent(paramValue) + hash;
    }
}

 



Please help me.

 

2 Replies

Avatar

Level 7

Hi @gayatri1012 ,

 

It seems like you're facing issues with downloading DAM user-generated collections in AEM. The provided code snippet attempts to download files from a collection by iterating through the collection items and initiating downloads for each item.

However, there are a few potential issues and improvements that could be made to this approach:

  1. Handling Large Collections: For large collections or collections with many items, iterating through each item and initiating downloads individually may not be efficient. This approach could lead to performance issues, especially if there are network latency or server-side processing delays.

  2. Download Window Limitations: Opening multiple download windows (window.open()) simultaneously may also encounter browser limitations, especially if there are too many concurrent downloads. Some browsers may block or limit the number of pop-up windows that can be opened simultaneously.

  3. Error Handling: The current code doesn't handle errors that may occur during the download process effectively. It's important to implement proper error handling to handle cases where downloads fail or encounter issues.

  4. Asynchronous Download: While the code uses promises for asynchronous execution, it's important to ensure that the downloads are handled asynchronously and in parallel. This allows for better performance, especially when downloading multiple files.

  5. Debugging: If there are issues with downloading specific files, it's important to debug and identify the root cause of the problem. This may involve logging additional information or analyzing network requests to understand where the issue occurs.

  6. Testing: Testing the download functionality with different collection sizes and file types can help identify potential issues and ensure that the code works reliably in different scenarios.

Here's a revised approach that addresses some of these points:

 

 

 

async function downloadCollection(collectionPath, collectionTitle) {
    if (!collectionPath) {
        console.error('Collection path is missing.');
        return;
    }

    const collectionItemsArr = collectionPath.split(';');
    if (collectionItemsArr.length === 0) {
        console.error('Empty collection.');
        return;
    }

    const downloadPromises = collectionItemsArr.map(itemPath => {
        const url = constructDownloadUrl(itemPath, collectionTitle);
        return downloadFile(url);
    });

    try {
        await Promise.all(downloadPromises);
        console.log('All files downloaded successfully.');
    } catch (error) {
        console.error('Error downloading files:', error);
    }
}

function constructDownloadUrl(itemPath, collectionTitle) {
    const filename = collectionTitle;
    let url = itemPath + '.assetdownload.zip/' + encodeURIComponent(filename);
    url = addParameter(url, '_charset_', 'utf-8');
    url = addParameter(url, 'licenseCheck', 'true');
    url = addParameter(url, 'flatStructure', 'true');
    return url;
}

// Remaining functions remain unchanged

 

In this revised approach:

  • We consolidate all download promises into an array and use Promise.all() to execute downloads in parallel.
  • Error handling is implemented using try-catch blocks around the Promise.all() call.
  • The constructDownloadUrl() function handles constructing the download URLs for each collection item.

Ensure that you thoroughly test this revised approach to ensure it meets your requirements and handles various scenarios effectively.

Avatar

Level 2

Thanks, but it didn't help me. As I called out my requirement is to download a collection that has multiple files in a single package.
also, we don't need to add the below code for each file path that is inside the collection. 

url = addParameter(url, '_charset_', 'utf-8');
    url = addParameter(url, 'licenseCheck', 'true');
    url = addParameter(url, 'flatStructure', 'true');