Get list of objects from s3 bucket (min.io or amazon) using promise

2k views Asked by At

I am trying to get a list of object name from s3 bucket using min.io javascript API (https://docs.min.io/docs/javascript-client-api-reference#listObjectsV2). The API returns a stream. However, I always get an empty list.

The example of the dataStream is:

{
  name: 'sample-mp4-file-1.mp4',
  lastModified: 2020-10-14T02:35:38.308Z,
  etag: '5021b3b7c402468d5b018a8b4a2b448a',
  size: 10546620
}
{
  name: 'sample-mp4-file-2.mp4',
  lastModified: 2020-10-14T15:54:44.672Z,
  etag: '5021b3b7c402468d5b018a8b4a2b448a',
  size: 10546620
}

My function

public async listFiles(
        bucketName: string,
        prefix?: string
    ): Promise<string[]> {
        const objectsList = [];
        await minioClient.listObjectsV2(bucketName, "", true, "", function(
            err,
            dataStream
        ) {
            if (err) {
                console.log("Error listFiles: ", err);
                return;
            }

            console.log("Succesfully get data");


            dataStream.on("data", function(obj) {
                objectsList.push(obj.name);
            });

            dataStream.on("error", function(e) {
                console.log(e);
            });

            dataStream.on("end", function(e) {
                console.log("Total number of objects: ", objectsList.length);
            });
        });

        return objectsList;
    }

Expected output is a list object name, [sample-mp4-file-1.mp4, sample-mp4-file-2.mp4]

1

There are 1 answers

1
Brad On BEST ANSWER

According to the documentation, listObjectsV2() is returning a stream, not a promise. Therefore, await is returning immediately, before objectsList will contain anything.

The API you're using has to support Promises if you want to await them.

You could work around this by doing something like this:

const objectsList = await new Promise((resolve, reject) => {
  const objectsListTemp = [];
  const stream = minioClient.listObjectsV2(bucketName, '', true, '');
  
  stream.on('data', obj => objectsListTemp.push(obj.name));
  stream.on('error', reject);
  stream.on('end', () => {
    resolve(objectsListTemp);
  });
});