0

I have removed error handling code as it is working (for simplicicty).

I have a function createOrder() which creates a new record in my MongoDB collection:

createOrder = order => new Promise((resolve, reject) => {
    Order.create({orderId: order});
    resolve();
});

getOrders() function that adds all current orders in the database to an array.

getOrders = _ => new Promise((resolve, reject) => {
    Order.find({buyerId: curUser.userId}, (err, orders) => {
        orders.map(order => order.status != 'cancelled' ? curUserOrders.push(order) : null);
    });
    resolve();
});

An external javascript file to post an order:

postOrder = () => {
    window.location = `/new_order/order=${JSON.stringify(itemArray)}`;
}

and the node application that "gets" the request:

app.get("/new_order/order=:order", (req, res) => {
    createOrder(JSON.parse(req.params.order))
    .then(getOrders)
    .then(_ => res.render("userprofile", {user : curUser, orders: curUserOrders}));
});

when i post a new order the postOrder() function is triggered and "userprofile" is displayed but none of the orders are displayed until i refresh the page again. Im still learning how promises work so im guessing the problem lies there. Please help :).

PiwiTheKiwi
  • 129
  • 1
  • 14

2 Answers2

0

Promises are used for asynchronous operations, but your example resoves the promise right away.

createOrder = order => new Promise((resolve, reject) => {
    Order.create({orderId: order});
    resolve();
});

You would write the create function like:

createOrder(order).then(()=>{
   // The asynchronous operation is completed!
})

But in your case it would happen the following:

createOrder = order => new Promise((resolve, reject) => {
    //Start the asynchronous operation ....
    Order.create({orderId: order});

    //... but you just resolve the operation right away.
    resolve();
});

A better example is probably the other function:

getOrders = _ => new Promise((resolve, reject) => {
    Order.find({buyerId: curUser.userId}, (err, orders) => {
        orders.map(order => order.status != 'cancelled' ? curUserOrders.push(order) : null);
    });
    // You just resolve without waiting for the callback of find.
    resolve();
});

What you want:

getOrders = _ => new Promise((resolve, reject) => {
    Order.find({buyerId: curUser.userId}, (err, orders) => {
        orders.map(order => order.status != 'cancelled' ? curUserOrders.push(order) : null);
        // Here we call resolve inside the callback and we wait for the find method and return the orders to the getOrders().then(orders => {}) call.
        resolve(orders);
    });

});

A Promise is what the name suggests, it provides you with a promise, that it will be fulfilled (resolved) at some point in the future. So you always want to wait with the resolve function until all operations are completed without errors.

Sever van Snugg
  • 571
  • 4
  • 12
0

Use it as callback like this

createOrder = order => new Promise((resolve, reject) => {
    Order.create({orderId: order}).then(()=>{resolve});
});
David van Driessche
  • 6,602
  • 2
  • 28
  • 41
basbas
  • 1
  • 1
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Aug 30 '20 at 20:07