Tengo problemas para entender cómo javascript pasa variables. Tengo el siguiente código ejecutándose en un controlador express
const { sessionID, defenderID, challengerID } = req.body; console.log('sessionID', sessionID); console.log('defenderID', defenderID); console.log('challengeID', challengerID); const newGame = await Game.start({ session: sessionID, defender: defenderID, challenger: challengerID });que está llamando a la siguiente definición
gameSchema.statics.start = async (session, defender, challenger) => { const date = new Date(); console.log('attempting to start a game'); console.log('session', session); console.log('defender', defender); console.log('challenge', challenger); const newGame = new Game({ defender: defender, challenger: challenger, startTime: date }); newGame.session.push(session); return await newGame.save().then((game) => game); }mi salida es
defenderID johndoe challengeID somechallenge attempting to start a game session { session: '620c29582ac275bd67cd3cca', defender: 'johndoe', challenger: 'somechallenge' } defender undefined challenge undefinedNo estoy exactamente seguro de dónde me estoy equivocando aquí, ya que estaba haciendo referencia a otro fragmento de código que funciona bien al hacer esto.
Está pasando un objeto como un solo argumento al método Game.start en el momento de llamar a la función, pero en la declaración de su función espera 3 argumentos, es decir, sesión, defensor y retador. Dado que la session es el primer argumento en la declaración de su función, obtiene el objeto en console.log para la session .
Puede solucionarlo pasando todos los argumentos individualmente al llamar al método de esta manera:
const { sessionID, defenderID, challengerID } = req.body; console.log('sessionID', sessionID); console.log('defenderID', defenderID); console.log('challengeID', challengerID); const newGame = await Game.start(sessionID, defenderID, challengerID);Otra forma de solucionarlo sería cambiar la declaración de la función para aceptar un solo argumento que es un objeto y puede desestructurar las propiedades de esta manera
gameSchema.statics.start = async ({ session, defender, challenger }) => { const date = new Date(); console.log('attempting to start a game'); console.log('session', session); console.log('defender', defender); console.log('challenge', challenger); const newGame = new Game({ defender: defender, challenger: challenger, startTime: date }); newGame.session.push(session); return await newGame.save(); }Y luego puedes llamar al método como ya lo estás haciendo.
const newGame = await Game.start({ session: sessionID, defender: defenderID, challenger: challengerID }); Además, no necesita usar .then después de llamar a .save() ya que ya está usando async await pattern y llamar await newGame.save() devolverá el documento del juego guardado.
return await newGame.save();El objeto completo se pasa al primer argumento (sesión con nombre):
{ session: sessionID, defender: defenderID, challenger: challengerID }Puede cambiar la llamada a:
const newGame = await Game.start(sessionID, defenderID, challengerID);o definición de método para:
async (obj) => { ... const newGame = new Game({ defender: obj.defender, challenger: challenger, startTime: date }); ...