Alex Reid
Alex Reid

Reputation: 1

Getting error Cannot read property 'then' of undefined when trying to chain promises Javascript

This is my first post so sorry if I have done it wrong.

I am trying to chain javascript promises together but when I run it I get the error Uncaught TypeError: Cannot read property 'then' of undefined at script.js:108 (anonymous) @ script.js:108

Do you know what i am doing wrong?

    const crates = {
    clothes: 8,
    hats: 20,
    toys: 50,
}

const orderToys = () => {
        new Promise((resolve, reject) => {
        if (crates.toys < 60){
            resolve('yes');
        } else {
            reject('no');
        }
    })
}

const sendMoney = (val) => {
        new Promise((resolve, reject) => {
        if(val === 'yes'){
            resolve('money sent');
        } else {
            reject('no order needed, do not sent money');
        }
    })
}

const orderConfirmed = (val) =>{
        new Promise((resolve, reject) => {
        if(val ==='money sent'){
            resolve('shipped');
        } else {
            reject('No money sent');
        }
    })
}

const delivered = (val) =>{
        new Promise((resolve, reject) => {
        if(val === 'shipped'){
            resolve('order completed');
        } else {
            reject('no order');
        }
    })
};

orderToys()
.then((firstVal) => {
    return sendMoney(firstval);
})
.then((secondVal) =>{
    return orderConfirmed(secondVal);
})
.then((thirdVal) =>{
    return delivered(thirdVal);
})
.then((fourthVal) =>{
    console.log(fourthVal);
})

Upvotes: 0

Views: 479

Answers (3)

M.A Shahbazi
M.A Shahbazi

Reputation: 1081

If you are using Promises then you must return the promise as well in order to preserve the promise chain:

const crates = {
    clothes: 8,
    hats: 20,
    toys: 50,
};

const orderToys = () => {
    return new Promise((resolve, reject) => {
        if (crates.toys < 60) {
            resolve('yes');
        } else {
            reject('no');
        }
    });
};

const sendMoney = (val) => {
    return new Promise((resolve, reject) => {
        if (val === 'yes') {
            resolve('money sent');
        } else {
            reject('no order needed, do not sent money');
        }
    });
};

const orderConfirmed = (val) => {
    return new Promise((resolve, reject) => {
        if (val === 'money sent') {
            resolve('shipped');
        } else {
            reject('No money sent');
        }
    });
};

const delivered = (val) => {
    return new Promise((resolve, reject) => {
        if (val === 'shipped') {
            resolve('order completed');
        } else {
            reject('no order');
        }
    });
};

Usage:

orderToys()
    .then((firstVal) => {
        return sendMoney(firstval);
    })
    .then((secondVal) => {
        return orderConfirmed(secondVal);
    })
    .then((thirdVal) => {
        return delivered(thirdVal);
    })
    .then((fourthVal) => {
        console.log(fourthVal);
    });

Or if you need to use async-await form:

(async function () {
    try {
        const value1 = await orderToys();
        const value2 = await sendMoney(value1);
        const value3 = await orderConfirmed(value2);
        await delivered(value3);
    } catch (e) {
        // Handle errors
        console.log(e);
    }
})();

Upvotes: 0

subashMahapatra
subashMahapatra

Reputation: 6847

You are not returning the promises from the function. You need to return the promise before you try to resolve them. Hope this helps.

const crates = {
    clothes: 8,
    hats: 20,
    toys: 50,
}

const orderToys = () => {
       return new Promise((resolve, reject) => {
        if (crates.toys < 60){
            resolve('yes');
        } else {
            reject('no');
        }
    })
}

const sendMoney = (val) => {
       return new Promise((resolve, reject) => {
        if(val === 'yes'){
            resolve('money sent');
        } else {
            reject('no order needed, do not sent money');
        }
    })
}

const orderConfirmed = (val) =>{
       return new Promise((resolve, reject) => {
        if(val ==='money sent'){
            resolve('shipped');
        } else {
            reject('No money sent');
        }
    })
}

const delivered = (val) =>{
      return  new Promise((resolve, reject) => {
        if(val === 'shipped'){
            resolve('order completed');
        } else {
            reject('no order');
        }
    })
};

orderToys()
.then((firstVal) => {
    return sendMoney(firstVal);
})
.then((secondVal) =>{
    return orderConfirmed(secondVal);
})
.then((thirdVal) =>{
    return delivered(thirdVal);
})
.then((fourthVal) =>{
    console.log(fourthVal);
})

Upvotes: 0

Barmar
Barmar

Reputation: 781731

Either return the promise:

const orderToys = () => {
  return new Promise((resolve, reject) => {
    if (crates.toys < 60) {
      resolve('yes');
    } else {
      reject('no');
    }
  })
}

or use the expression form of the arrow function.

const orderToys = () =>
  new Promise((resolve, reject) => {
    if (crates.toys < 60) {
      resolve('yes');
    } else {
      reject('no');
    }
  });

Upvotes: 2

Related Questions