Search code examples
javascriptnode.jscontentfulcontentful-management

Iterate items in array through NodeJS script


I am trying to find a solution to creating multiple assets in Contentful using the contentful-management API.

The nodeJS script to achieve a single creation of an asset is

const client = contentful.createClient({
  accessToken: '<content_management_api_key>'
})

client.getSpace('<space_id>')
.then((space) => space.getEnvironment('<environment-id>'))
.then((environment) => environment.createAssetWithId('<asset_id>', {
  title: {
    'en-US': 'Example 1'
  },
  file: {
    'en-US': {
      contentType: 'image/jpeg',
      fileName: 'example1.jpeg',
      upload: 'https://example.com/example1.jpg'
    }
  }
}))
.then((asset) => asset.processForAllLocales())
.then((asset) => asset.publish())
.then((asset) => console.log(asset))
.catch(console.error)

Which is quite simple and easily implemented. However, when wanting to create multiple assets, this does not work.

After many hours looking for a documented way to achieve this, with no avail, I came to

const contentful = require('contentful-management');
const assets = require('./assetObject.js');

async () => {
  const client = contentful.createClient({
    accessToken: '<content_management_api_key>'
  });

  const space = await client.getSpace('<space_id>');
  const environment = await space.getEnvironment('<environment-id>');
  const createdAssets = await Promise.all(
    assets.map(
      asset =>
        new Promise(async () => {
          let cmsAsset;

          try {
            cmsAsset = await environment.createAssetWithId(asset.postId, {
              fields: {
                title: {
                  'en-US': asset.title
                },
                description: {
                  'en-US': asset.description
                },
                file: {
                  'en-US': {
                    contentType: 'image/jpeg',
                    fileName: asset.filename,
                    upload: asset.link
                  }
                }
              }
            });
          } catch (e) {
            throw Error(e);
          }
          try {
            await cmsAsset.processForAllLocales();
          } catch (e) {
            throw Error(e);
          }
          try {
            await cmsAsset.publish();
          } catch (e) {
            throw Error(e);
          }
        })
    )
  );
  return createdAssets;
};

assetObject.js

[
 {
    link: 'https://example.com/example1.jpg',
    title: 'Example 1',
    description: 'Description of example 1',
    postId: '1234567890',
    filename: 'example1.jpeg'
  }, ... // Many more
]

This, when running, produces no errors, nor does it do anything. What have I done wrong? Is this the method I should use?


Solution

  • A new promise need to be "resolved" and "rejected" so for me the code should look like

     const createdAssets = await Promise.all(
        assets.map(
          asset =>
            new Promise(async (resolve, reject) => {    
              try {
                const cmsAsset = await environment.createAssetWithId(asset.postId, {
                  fields: {
                    title: {
                      'en-US': asset.title
                    },
                    description: {
                      'en-US': asset.description
                    },
                    file: {
                      'en-US': {
                        contentType: 'image/jpeg',
                        fileName: asset.filename,
                        upload: asset.link
                      }
                    }
                  }
                });
                await cmsAsset.processForAllLocales();
                await cmsAsset.publish();
                resolve(cmsAsset);
              } catch (e) {
                reject(e);
              }
            })
        )
      );
      return createdAssets;
    

    Hop it can help