- [Instructor] We will now implement the service responsible
for the order management in MySQL.
For that open server, services, OrderService
and there we already started implementing this class,
but our order management, we will use transactions.
Transactions are a feature of the most relational databases
and they in a nutshell,
make sure that either all commands
on the database are executed or none.
This means, if you create one record in one table
and few other records in another table
and something goes wrong along the way,
no record will be created.
So it's either everything or nothing
if those instructions are performed in a transaction.
To later being able to run, work in a transaction,
I will now create a new function async in transaction.
And this function, just expects one argument, this is work.
And work as you will see later
is actually a function.
Now I will first start the transaction.
So I add const t equals await,
this.client, that's sequelize
and then transaction.
Next, I will add a try-catch block.
Try catch.
And in the try block,
I will now add await, work, and I pass in the transaction.
So I'm executing the function that was passed
into this function
and I provide the transaction as an argument.
After that I will return t the transaction commit.
So committing a transaction means, everything went fine.
Now it can be written to the database.
If an error occurs,
so catch error, I will do t.rollback.
So this will roll back anything that has been done
and returns to the state before the transaction started
and I will throw an error here,
to rethrow the error to the caller.
Next, I will also add a method to create an order.
For that I add async, create.
And this create method expects a user,
the items of the order and again, the transaction.
And in there, I know add const order equals await,
this models.
That's the property we created in the constructor.
Order.create, that's provided by sequelize.
And in create, I will now pass an object.
And this object now contains the userId
which is user.id,
the email, which is user.email
and the status, which is by default now, Not Shipped.
So that's the initial status of every order.
And his second argument,
I also pass in the transaction to this create function.
So transaction is t.
Now I created this order.
Now I have to create also the records in order item.
And for that, I will now iterate over the items,
but actually this is something that can be done in parallel.
So for that, I will not add return Promise.all.
So this is a promise
and that will now map through the items,
so that items.map and inside this map function,
and add an async function that takes an item
and in there, I will now create this order item,
const orderItem equals await,
this.models.OrderItem.create.
So that similar to order.
And then now, pass in the data
for where the items are at sku is item.sku,
quantity is item.qty,
price is item.price.
And the name of the item is item.name.
I have a typo here.
It's item not item.
And in the end here, I will now return order addOrderItem,
because this is a method that is now provided
by sequelize magically,
because we defined this relationship before.
And this method now takes this one order item
and in curly brackets, one more argument it's transaction.
And the transaction is now, again,
this t that was passed in.
So this mapping function now returns a map of promises
and these promises are then resolved
by a promise all.
So this now all runs basically in parallel
which is of course, a lot faster
if you have many items to iterate over and add to the order.
Next, let's add one more method
that gets us all items in order.
So this is async getAll.
And this is now very simple return,
this.models.Order findAll.
And I pass in a where clause.
So this is the clause, but this is empty.
So it's curly brackets.
And they also have to tell sequelize now
to resolve this dependency to the order items.
So I add include and in curly brackets,
I add this models.OrderItem.
In the end, I also want to add one more method,
this is then to set the status of an order.
As you know, now they're not shipped,
but I want to set them to ship later.
So I add now async, set status.
And this takes now, an orderId and the status to be set.
And here return this.models Order.update
and I have to provide what should be updated.
So I could now write status: status,
but in short, this can be written,
it's just adding status here.
So if the property is the same name
as the variable that you set,
you can just put in just the property name.
And then I have to add a where clause,
because I only want to update a given order.
So add where and the clause is here
and it looks a little bit like dealing with MongoDB,
id: orderId.
Behind the scenes, of course and you will see this
in the console output later,
sequelize creates SQL statements from that.
So with that done, all that is missing
is now varying up our basket page to use this order service.
And we will do this in the next video.