Esta es una aplicación nodejs/express MVC. Tengo un modelo personalizado llamado MyModel (no realmente, pero por privacidad, supongamos que ese es el nombre). Las propiedades de la clase se establecen como nulas de forma predeterminada:
export class MyModel { /* ----- FIELDS ----- */ protected _id: string = null; protected _name: string = null; ...El constructor solo establece la propiedad del nombre, todas las demás propiedades las establecen los activadores de la base de datos. Entonces, en mi método de guardado (que persiste en la base de datos), funciona así:
async save() { let client:PoolClient = null; try { client = await pool.connect(); let query; if (this._id === null) { query = { name: 'insertMyModel', text: 'INSERT INTO my_model (name) VALUES ($1::text) RETURNING id', values: [this._name], rowMode: 'array', }; } else { ... } const result = await client.query(query); if (this._id === null) { this._id = result.rows[0][0]; ...El controlador, simplemente (por ahora) devuelve MyModel a la cadena, que debería mostrar la identificación devuelta.
public async new(req, res) { try { const mymodel = await MyModel.new(req.params.name); res.send(mymodel.toString()); } catch (error) { res.status(400).send(error); } }Y (gracias @Barmar por notarlo) olvidé incluir la nueva función de MyModel, así que la agregué aquí. Esto construye la nueva instancia de MyModel y luego llama a guardar.
public static async new(name: string) : Promise<GekModel> { if (name === undefined || name === null || (name = name.trim()) === '') { name = uniqueNamesGenerator(); } const mymodel = new MyModel(name); mymodel.save(); return mymodel; }Usando la depuración interactiva, he determinado que en el método de guardado, de hecho, la base de datos está devolviendo correctamente la ID. Y he visto que en el método de guardar, la identificación devuelta se asigna a la propiedad _id. Sin embargo, cuando vuelvo a la nueva del controlador, la propiedad _id vuelve a ser nula. follar
Supongo que esto tiene algo que ver con la naturaleza asíncrona de la misma. Pero, estoy perdido. Me encantaría cualquier idea!
Muchas gracias @Barmar por la sugerencia de escribir una versión reproducible de código mínimo de este problema. Pude reducirlo a 24 líneas y me di cuenta de que el problema estaba en la línea mymodel.save(). Estaba llamando a guardar sincrónicamente, cuando es un método asíncrono. Por lo tanto, se llamó al método toString() antes de que se estableciera la identificación. Agregué un "esperar" antes de eso y está funcionando ahora.