Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass variable down through promise chain

I'm slightly new to promises so please excuse my lack of knowledge. The code below highlights what I want to do but clearly I am unable to.

var token = "";
var id = "";
var cms = {
    login: function () {
        return request({
            "method": "POST",
            "uri": process.env.CMS_URL + "/cms/login",
            "json": true,
            "body": {
                "email": "xxxxxxx",
                "password": "xxxxx"
            }
        }).then(response => {
            console.log("Successfully logged in to cms. Access token: " + response);
            token = response;
        }).catch(error => {
            console.log("Couldn't get access token from cms");
        });
    },
    createCollection: function (token) {
        return request({
            "method": "POST",
            "uri": process.env.CMS_URL + "/cms/collection",
            "json": true,
            "headers": {
                "X-Cms-Token": token
            },
            "body": {
                "name": "Acceptance test collection",
                "type": "manual"
            }
        }).then(response => {
            console.log("Successfully created a collection.");
            id = response.id;
        }).catch(error => {
            console.log("Collection already exists");
        });
    },
    deleteCollection: function (token, id) {
        return request({
            "method": "DELETE",
            "uri": process.env.CMS_URL + "/cms/collection" + id,
            "json": true,
            "headers": {
                "X-Cms-Token": token
            }
        }).then(response => {
            console.log("Successfully deleted collection.");
        }).catch(error => {
            console.log("No collection to delete");
            console.log(error);
        });
    }
};
var createCollectionCms = function (token, id) {
    return new Promise((resolve) => {
        cms.login()
            .then(zebedee.createCollection(token))
            .then(zebedee.deleteCollection(token, id));
        setTimeout(resolve, 6000);
    });
}
createCollectionCms();

I need to run each function and pass in "token" and "id". By doing it the way above each function runs at the same time. I need them to execute after each other but pass down the required variables.

Essentially I need to log in, create a "collection", the delete the "collection". This is part of some tests i'm setting up.

like image 413
user924248 Avatar asked Sep 14 '25 08:09

user924248


1 Answers

here's a readable and synchronous-looking alternative to using Promises using async/await (which actually still uses Promises under the hood)

// returns a Promise whose response is the token
const requestAccessToken = cmsUrl => request(/* request options with cmsUrl */)

// returns a Promise whose response is the collectionId
const createCollection = token => request(/* request options with token */)

// returns a Promise whose response is given by deleting the respective collection
const deleteCollection = collectionId => request(/* request options with collectionId */)

// create and execute an async function that puts all these functions together in a synchronous manner
const createThenDeleteCollection = async cmsUrl => {
  try { // if at any time an error is thrown, the error is caught and logged
    const token = await requestAccessToken(cmsUrl)
    const collectionId = await createCollection(token)
    const responseFromDeletingCollection = await deleteCollection(collectionId)
    console.log(responseFromDeletingCollection)
  } catch (err) {
    console.error(err)
  }
}
createThenDeleteCollection(process.env.CMS_URL)

a caveat that comes with using this method is that it isn't supported by IE if you're executing it in the browser, and if you're executing in Node, you'll need to use at least version 7.6

like image 76
feihcsim Avatar answered Sep 15 '25 20:09

feihcsim