1

I have a following function, which works, when passed a new user data . it saves the object and the child object into the mysql table successfully. but how do i return the object back , once saved to the database, given i'm using sequelize transaction.

static async add(user) {
    let transaction; 
      try {
          // get transaction
        transaction = await models.sequelize.transaction();

        //  *****how to return the newly created user *****************************************

        models.User.create(user).then(newUser => {
          const id = newUser.id;

           //save address 
          if(user.address){

              address.userId = id;
              models.Address.create(address); 

          }
        }).catch(error => {
          throw error;
        }); 

        await transaction.commit();

      } catch (error) {
          console.log(error); 
            // Rollback transaction 
          if (transaction) await transaction.rollback();
          throw error;
      }
    }
arve
  • 569
  • 2
  • 10
  • 27
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – ggorlen May 27 '20 at 21:27
  • 1
    You just mixed up two approaches: async/await and `then` chain. I recommend to use async/await and call `models.User.create(user)` as `const newUser = await models.User.create(user)`. Also don't forget to pass a transaction object to all sequelize queries inside it explicitly like this: `models.User.create(user, { transaction })` – Anatoly May 27 '20 at 21:40
  • 1
    @Anatoly - thanks. with this const newUser = await models.User.create(user, {transaction}); I don't have to await transaction. I need to create/save address object as well, once user is created. How do I do that with aysnc/await. would you mind give me sample code snippet? – arve May 31 '20 at 20:28
  • 2
    `if(user.address){ address.userId = id; await models.Address.create(address, { transaction }); }` – Anatoly May 31 '20 at 21:58
  • @Anatoly - I know this is an old question but, I am still not sure if I'm doing this correctly. can you post complete code sample , on creating user , then address and returning the user object at the end. – ozil Aug 12 '20 at 22:57

1 Answers1

2

Try to create an auto-transaction, use await and indicate transaction in models's create functions:

static async add(user) {
      try {
        const createdUser = await models.sequelize.transaction(transaction => {
          const newUser = await models.User.create(user, { transaction })
           //save address 
          if(user.address){
            address.userId = newUser.id;
            await models.Address.create(address, { transaction }); 
          }
          return newUser;
        });
        // if you are here it means transaction already commited
        return createdUser;
      } catch (error) {
          // if you are here it means transaction already rolled back
          console.log(error); 
          throw error;
      }
    }
Anatoly
  • 20,799
  • 3
  • 28
  • 42
  • I apologize in advance . one last request on this, I'm really stuck on this and have no idea on how to do this. if i have to update the address (user can have multiple address) , when I am updating the user. how should i do this. I have created associations and now I can pull all the addresses for a user => const updateUser = await models.User.findOne({ where: { id: Number(id) },include: [ {model: models.Address, as: 'addresses'}] }); But when it comes to update, do i update everything at once? – arve Aug 16 '20 at 02:29
  • 1
    You can update user and addresses at once using `set`+`save` or `update` method. See https://sequelize.org/v5/class/lib/model.js~Model.html#instance-method-set – Anatoly Aug 16 '20 at 21:24