简体   繁体   中英

Koa/Node.js - Use multiple models within one controller function

I am attempting to create a new 'Vault' from a Post Request from my frontend (built in React) using Mongoose Schema.

When I hit the create button in my app, the Post Request initiates, but returns:

POST http://localhost:3000/vaults/create 500 (Internal Server Error)

When my controller function createVault() is initiated, it will successfully create a 'Vault' from the model (see below):

//Create a vault
module.exports.createVault = async (ctx, next) => {
  if ('POST' != ctx.method) return await next();
    try {
      if (!ctx.request.body.name) {
      ctx.status = 404
  }
  //Create new vault
  const vault = await Vault.create({
    name: ctx.request.body.name,
    url: ctx.request.body.url,
    description: ctx.request.body.description
  });

   await vault.save();

   //Return vault
   ctx.body = vault;
   ctx.status = 201;
 }
 catch (error) {
   if (error) {
     console.log('Error in the createVault controller:', error);
     ctx.status = error.response.status;
     ctx.body = error.response.data;
   }
 }
}

However, my problem occurs when I try to add a second Schema model; I am attempting to create a 'Crypt' from each of the items in the ctx.request.body.crypts array (see below):

//Create a vault
module.exports.createVault = async (ctx, next) => {
  if ('POST' != ctx.method) return await next();
  try {
    if (!ctx.request.body.name) {
      ctx.status = 404
    }
    //Create new vault
    const vault = await Vault.create({
      name: ctx.request.body.name,
      url: ctx.request.body.url,
      description: ctx.request.body.description
    });
    //Create new crypts
    const promises = await ctx.request.body.crypts.map(crypt => Crypt.create({
      name: crypt
    }));
    //Add reference to vault
    const crypts = await Promise.all(promises);
    vault.crypts = crypts.map(crypt => crypt._id);
    await vault.save();

    //Return vault and crypts
    ctx.body = [vault, crypts];
    ctx.status = 201;
  }
  catch (error) {
    if (error) {
      console.log('Error in the createVault controller:', error);
      ctx.status = error.response.status;
      ctx.body = error.response.data;
    }
  }
};

The error I receive say I cannot map over an undefined object, although I am using const crypts = await Promise.all(promises);

Can anyone suggest a correct way around this problem? Many thanks.

I managed to fix my problem by creating a function called cleanBody(body) which manually parsed the data for me to use.

I logged typeof ctx.request.body which returned a string and revealed my problem. The cleanBody(body) function just check if the body was an object, then used JSON.parse() if it was a string (see below):

const cleanBody = body => {
  return typeof body !== 'object' ? JSON.parse(body) : body;
};

My mistake was assuming APIs from Postman and APIs called in the app would pass the same data, even when everything looks the same

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM