En el minuto 07:29 también se puede poner findById(id) en vez de findOne({_id: id})
Conocer y comprender cómo se realizan las conexiones hacia los servidores a través de internet y sus implicaciones en el desarrollo de servidores
Bienvenida y presentación del curso
Qué es Node y cómo instalarlo
¿Qué son y cómo se usan las peticiones HTTP?
Métodos, cabeceras y estados
Cuerpo y query de la petición
Crear un servidor HTTP en Javascript, y comenzar a escuchar y responder peticiones desde un cliente .
Crear un servidor HTTP desde NodeJS
¿Cómo pueden venir las peticiones?
Recibir información desde el cliente: Body y Query
Información contextual: Leer las cabeceras
Tipos de respuesta: Vacía, plana, con datos y estructurada
Respuestas coherentes
Servir archivos estáticos
Errores: Cómo presentarlos e implicaciones en la seguridad
Comprender y desarrollar la arquitectura básica de un backend en NodeJS, y comunicarse entre módulos
Conceptualmente: Rutas, controladores y bases de datos
Rutas y capa de red: Responsabilidades y límites
Controladores: Definiendo la lógica de negocio
Almacenando la información en una base de datos
Utilizar una base de datos para definir, modelar, almacenar y recuperar la información de nuestra aplicación
Tipos de Bases de Datos: Relacionales y No Relacionales
Crear y Configurar tu Base de Datos con MongoDB
MongoDB: Almacenar y leer datos
MongoDB: Actualizar datos
MongoDB: Consultar datos
MongoDB: Eliminar Datos
Gestionar conexiones a la base de datos desde la API
Uso de entidades para crear aplicaciones escalables
Escalando la arquitectura: Múltiples entidades
Relacionando nuestras entidades
Cómo recibir ficheros desde NodeJS
Guardar el fichero en el servidor
Conocer el protocolo de websockets, e implementar comunicación cliente/servidor con SocketIO.
WebSockets: Qué son, por qué son interesantes y cómo usarlos
Manejo de Websockets con NodeJS
Conectar la API al servidor de WebSockets
Revisión de lo aprendido, y próximos pasos
Revisión y próximos pasos
Tips para escalar nuestro proyecto
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Carlos Hernández
Aportes 47
Preguntas 6
En el minuto 07:29 también se puede poner findById(id) en vez de findOne({_id: id})
Pueden utilizar esto:
const updatedMessage = await Message.findOneAndUpdate(
{ _id: id },
{ message },
{ new: true }
)
return updatedMessage
Para encontrar el mensaje y actualizar en un solo paso.
¿Sería buena práctica utilizar async/await dentro de una promesa? 🧐
He estado buscando información y he encontrado esto:
Ese error del await en el minuto 06:37 es buenísimo
Creo que en Mongoose podemos encontrar un registro y actualizarlo en la misma petición.
https://mongoosejs.com/docs/tutorials/findoneandupdate.html
Ejecuta la actualiacion, validando en la base de datos se ve el cambio realizado y la respuesta esta bien. Pero al final muestra este error.
[response error] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
(node:17296) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at ServerResponse.header (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:158:21)
at Object.exports.error (C:\Users\fgarcia\Platzi\CursoNodeJS\network\response.js:9:31)
at C:\Users\fgarcia\Platzi\CursoNodeJS\components\message\network.js:32:22
at processTicksAndRejections (internal/process/task_queues.js:94:5)
(node:17296) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:17296) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Si les aparece el siguiente error y no saben como eliminarlo aun si se les actualiza la informacion, se debe entonces eliminar el “RES.SEND(‘OK’)”, en mayus para que lo identifiquen en el archivo NETWORKS.JS, en la promesa ya que se considera redundante para el sistema cayendo en error logico.
[response error] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
(node:17296) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at ServerResponse.header (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (C:\Users\fgarcia\Platzi\CursoNodeJS\node_modules\express\lib\response.js:158:21)
at Object.exports.error (C:\Users\fgarcia\Platzi\CursoNodeJS\network\response.js:9:31)
at C:\Users\fgarcia\Platzi\CursoNodeJS\components\message\network.js:32:22
at processTicksAndRejections (internal/process/task_queues.js:94:5)
(node:17296) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:17296) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Hola Devs:
Aca les traigo mi solucion usando TypeScript en el proyecto:
-El Network del componente Message:
-El Controller del componente Message:
-El Store del componente Message:
-Aca les dejo el commit exacto de esta clase:Click Aqui
-Recuerda, #NuncaParesDeAprender 💚
Validacion de errores
El codigo funciona si se ingresan los parametros en forma correcta, sin embargo en mi caso aparecio un error al llamar a la funcion usando el formato de get localhost:3000/message/id=5ff67a187350d52c30af11d5
Si bien lo pude corregir modificando el llamado usando el formato de patch
localhost:3000/message/5ff67a187350d52c30af11d5
El programa debe validar los errores, puede hacerse en dos formas
Forma 1: Validar en store/updateText y en controller/updateMessage
En store.js actualizar la funcion updatetext segun el siguiente codigo
async function updateText(id, message){
try{
const foundmessage=await Model.findOne({_id: id })
foundmessage.message = message;
const newMessage= await foundmessage.save();
return newMessage;
}
catch(e){
console.log('Error en updateText: '+e);
const newMessage='';
return newMessage;
};
}
En controller.js actualizar la funcion updateMessage segun el siguiente codigo
function updateMessage(id, message){
return new Promise( async (resolve,reject)=>{
if(!id || !message){
reject('updateMessage:invalid data');
return false;
}
const result = await store.updateText(id, message);
//verifica error
if(result==''){reject('updateMessage: id no encontrado')}
else{resolve(result);}
} )
}
Esta forma permite precision en la identificacion del problema, pero requiere mayor codificacion
Forma 2: Validar en controller/updateMessage
En controller.js actualizar la funcion updateMessage segun el siguiente codigo
function updateMessage(id, message){
return new Promise( async (resolve,reject)=>{
if(!id || !message){
reject('updateMessage:invalid data');
return false;
}
try{
const result = await store.updateText(id, message);
resolve(result);
}
catch(e){
reject('updateMessage: id no encontrado')
}
} )
}
Esta forma es muy general y el programador debe conocer de antemano “que puede fallar” para indicar el error, pero es mas sencilla de codificar.
Conclusion
Aunque tenga mayor codificacion, recomendaría utilizar la forma 1
Espero que sirva de ayuda
Saludos
También se puede usar la función findByIdAndUpdate en store.js
async function updateText(id, message){
const updatedMessage = await Model.findByIdAndUpdate(id, {message}, {new: true});
return updatedMessage;
}
las promesas de por si no son asincronas? porque la necesidad de colocar un async await? no entiendo :c
Version con arrow functions y async/await
NETWORK:
//
router.patch('/:id', async (req, res) => {
const { id } = req.params;
const { message } = req.body;
try {
const data = await controller.updateMessage(id, message);
response.success(req, res, data, 201);
} catch (error) {
console.log(error);
response.error(req, res, "Error", 400, error)
}
});
STORAGE:
const updateText = async (id, message) => {
const requestedMessage = await Model.findById(id)
requestedMessage.message = message;
const messageUpdated = await requestedMessage.save();
return messageUpdated;
}
CONTROLLER:
const updateMessage = (id, message) => {
return new Promise( async (resolve, reject) => {
if (id && message) {
try {
const data = await storage.updateText(id, message);
resolve(data);
} catch (error) {
reject(new Error(error));
}
}else {
reject(new Error('Missing params'));
}
});
};
Es necesario poner un asyc/away tanto en la promesa como en el updatetext del store.js?
no es medio redundante estar pasando los mismos parametros siempre, se podria ahorrar la logica de network y pasarle directamente el controller no? asi no se arma lio con promesas async awaits y todo eso.
Hecho en 2022, utilice la función de Mongo llamada findByIdAndUpdate, lo que quedo así:
async function updateText(id, message) {
const newMessage = await Model.findByIdAndUpdate(
id,
{ message: message },
{ new: true }
);
return newMessage;
}
Según leí, el uso del parámetro {new : true} es para que se retorne el documento después de que se haya actualizado.
todo el mundo en plena discordia y yo use updateOne() en una sola linea salio
async function updateMessage(id,message){
//algo para registrar un mensaje
updatedMessage = await Model.updateOne({_id:id},{message:message})
return updatedMessage
}
Que bueno que le salio el error del async por fuera al profesor, no se si yo lo hubiese encontrado tan rapido
Mi codigo por si alguien no le sirve:
Network:
const express = require("express");
const response = require("../../network/response");
const controller = require("./controller");
const router = express.Router();
router.get("/", function (req, res) {
controller
.getMessages()
.then((messageList) => {
response.success(req, res, messageList, 200);
})
.catch((e) => {
response.error(req, res, "Unexpected Error", 500, e);
});
});
router.post("/", function (req, res) {
controller
.addMessage(req.body.user, req.body.message)
.then((fullMessage) => {
response.success(req, res, fullMessage, 201);
})
.catch((e) => {
response.error(
req,
res,
"Error Inesperado" + e,
500,
"Es solo una simulacion"
);
});
});
router.patch("/:id", function (req, res) {
console.log(req.params.id);
controller
.updateMessage(req.params.id, req.body.message)
.then((data) => {
response.success(req, res, data, 200);
})
.catch((e) => {
response.error(req, res, "Error interno", 500, e);
});
});
module.exports = router;
store
const db = require("mongoose");
const Model = require("./model");
//----------mongodb+srv://test:<password>@cluster0.rjtat.mongodb.net/<dbname>?retryWrites=true&w=majority
db.Promise = global.Promise;
db.connect(
"mongodb+srv://test:[email protected]/Telegrom?retryWrites=true&w=majority",
{ useNewUrlParser: true, useUnifiedTopology: true, dbName: "Telegrom" }
)
.then(() => console.log("[db] Conectada con éxito"))
.catch((err) => console.error("[db]", err));
console.log("[db] Conectada con exito");
const list = [];
function addMessage(message) {
const myMessage = new Model(message);
myMessage.save();
}
async function getMessages() {
/* return list; */
const messages = await Model.find();
return messages;
}
async function updateText(id, message) {
const foundMessage = await Model.findOne({
_id: id,
});
foundMessage.message = message;
const newMessage = await foundMessage.save();
return newMessage;
}
module.exports = {
add: addMessage,
list: getMessages,
updateText: updateText,
};
Controller:
const store = require("./store");
function addMessage(user, message) {
return new Promise((resolve, reject) => {
if (!user || !message) {
console.error("[messageController] No hay usuatio o mensaje");
return reject("Los datos son incorrectos");
}
const fullMessage = {
user: user,
message: message,
date: new Date(),
};
store.add(fullMessage);
resolve(fullMessage);
});
}
function getMessages() {
return new Promise((resolve, reject) => {
resolve(store.list());
});
}
function updateMessage(id, message) {
return new Promise(async (resolve, reject) => {
console.log(id);
console.log(message);
if (!id || !message) {
reject("Invalid Data");
return false;
}
const result = await store.updateText(id, message);
resolve(result);
});
}
module.exports = {
addMessage,
getMessages,
updateMessage,
};
Hola
En mi caso me salia este mensaje
(node:14056) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "id=5ff67a187350d52c30af11d5" at path "_id" for model "Message"
at model.Query.exec (F:\platzi\backendnode\node_modules\mongoose\lib\query.js:4358:21)
at model.Query.Query.then (F:\platzi\backendnode\node_modules\mongoose\lib\query.js:4450:15)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use
node --trace-warnings …to show where the warning was created)
(node:14056) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict
(see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode).
(rejection id: 1) (node:14056) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Despues de revisar multiples entradas en el foro y enlaces externos me di cuenta que mi error era la forma de como llamar a la API
Al inicio la llamaba de esta forma, como si fuera un get normal con el nombre de la variable y su valor:
localhost:3000/message/id=5ff67a187350d52c30af11d5
y la forma correcta es la siguiente, si utilizar el nombre de variable
localhost:3000/message/5ff67a187350d52c30af11d5
Espero que les sirva de ayuda
Saludos
Nota: si usas findOne en lugar de findById despues save() no funciona de la misma manera
El mejor profe, ojalá los de la facultad fueran así
Me gustaria que se incluyera un poco mas acerco del manejo de errores, que tal si el id que envio no existe?
En mi caso lo maneje con try/catch y retornando un __new Error. __
Igual se puede utilizar findByIdAndUpdate en este 2023
Model.findByIdAndUpdate(id, {data}, { new: true });
esto puede ayudar para conectarse con atlas
const mongoose = require(‘mongoose’);
mongoose.set(‘strictQuery’, true);
const Model = require(’./model’)
const uri = ‘aquí_uri_de_altas’;
async function connect () {
try{
await mongoose.connect(uri);
console.log("Conectado a Mongo DB");
} catch (error){
console.error(error);
}
}
connect();
para poder actualizar los datos desde la aplicación hacia mongo
por lo que vamos a incrementar la funcionalidad de actualizar datos
Primero creamos dentro de la carpeta message un archivo con nombre model.js y construir un modelo de mensaje que va a ingresarse o actualizarse
model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mySchema = new Schema({
user: String,
message: {
type: String,
required: true,
},
date: Date,
});
const model = mongoose.model('Message', mySchema);
module.exports = model;
posteriormente creamos la funcionalidad dentro del archivo store.js
const db = require('mongoose');
const { findById, findOne } = require('./model');
const Model = require('./model');
require('dotenv').config();
async function updateText(id, message) {
const foundMessage = await Model.findOne({_id: id});
foundMessage.message = message;
return await foundMessage.save();
}
luego hacemos una funcionalidad dentro del archivo controller.js
const store = require('./store');
function updateMessage(id, message) {
return new Promise(async (resolve, reject) => {
console.log(id, message);
if (!id || !message){
reject('invalid data');
return false;
}
const result = await store.updateText(id, message);
resolve(result);
});
}
finalmente creamos la funcionalidad de actualización en network.js
const express = require("express");
const response = require("../../network/response");
const controller = require("./controller");
const router = express.Router();
router.patch('/:id', async(req, res)=> {
await controller.updateMessage(req.params.id, req.body.message)
.then((data) => {
response.success(req, res, data, 200);
})
.catch(e => {
response.error((req, res, 'Error interno', 500, e));
});
});
no tengo errores de momento pero me pasa que no puedo visualizar el id para modificar el mensaje
Código con ES6+:
Ruta: componente/message/network.js
router.patch('/:id', async (req,res)=>{
try {
console.log(req.body.message, 'acs')
const{ id } = req.params;
const { message } = req.body;
console.log(message, 'aqui')
const data = await updateMessage(id, message);
response.success(req, res, data, 200);
} catch (error) {
response.error(req, res, 'Informacion invalida', 500, 'Error en el controlador');
}
});
Ruta: componente/message/controller.js
function updateMessage(id,message) {
return new Promise(async (resolve,reject)=>{
console.log(id)
console.log(message);
if(!id || !message){
reject('Invalid data');
}
const result = await store.update(id,message);
resolve(result);
})
}
Ruta: componente/message/store.js
async function updateText(id,message) {
const updateMessage = await Model.findByIdAndUpdate(
{_id:id},
{message},
{new : true}
)
return updateMessage;
}
Esta parte de mongo fue realmente perdida porque los videos no estan actualizados con la configuracion que muestra mongo actualmente
Hola comparto mi solucion:
const updateMessage = async (id, message) => {
const updatedMessage = await Model.findByIdAndUpdate(id, {
$set:{message}
}, (err, doc) => {
err?console.log('[store-message] => Error al actualizar el mensaje: '+err):false;
doc?console.log('[store-message] => Registro actualizado!'):false;
});
updatedMessage?updatedMessage.save():false;
return updatedMessage;
}
Al actualizar va salir un Warning de deprecation, la solucion es la siguiente:
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('useUnifiedTopology', true);
Remplazar mongoose con la constante creada al momento de hacer el require a mongoose.
Al usar lo anterior podemos evitar las opciones que pasamos al conectarnos a la base de datos.
Put tambien es para modificar o me equivoco… !!
Amigos yo tengo este problema todo funciona bien pero me sale este mensaje y no se que es ya revise el video muy bien en busca de errores
Example app listening on port 3000!
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (C:\Users\Moises\Documents\node\cursoDeNodejs\node_modules\express\lib\response.js:771:10)
at ServerResponse.setHeader (_http_outgoing.js:470:11) nse.js:170:12)
at ServerResponse.header (C:\Users\Moises\Documents\node\cursoDeNodejs\node_modules\express\lib\resnse.js:267:15)ponse.js:771:10) nse.js:158:21)
at ServerResponse.send (C:\Users\Moises\Documents\node\cursoDeNodejs\node_modules\express\lib\response.js:170:12) etwork.js:27:18)
at ServerResponse.json (C:\Users\Moises\Documents\node\cursoDeNodejs\node_modules\express\lib\response.js:267:15) they are sent to the client
at ServerResponse.send (C:\Users\Moises\Documents\node\cursoDeNodejs\node_modules\express\lib\response.js:158:21) ponse.js:771:10)
at Object.error (C:\Users\Moises\Documents\node\cursoDeNodejs\network\response.js:11:35) nse.js:170:12)
at controller.updateMessage.then.catch.e (C:\Users\Moises\Documents\node\cursoDeNodejs\components\mnse.js:267:15)essage\network.js:30:18) nse.js:158:21)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:13608) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated eitheessage\network.js:30:18)r by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) r by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled wi
(node:13608) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future,
promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[nodemon] restarting due to changes…
[nodemon] starting node server.js
conectado a DB
Example app listening on port 3000!
Buenas, a mi al ejecutar el PATCH y modificar el message, me sale el siguiente error:
[response_error]: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 20
Pero sí que se modifica correctamente en la BBDD, alguna idea?
Excelente clase profe!!!
Excelente la forma de update
Buenas noches companeros. Alguien sabe porque de da este error cuando trato de actualizar el mensaje?
(node:69315) UnhandledPromiseRejectionWarning: TypeError: Cannot set property 'message' of null
at Object.updateText (/Users/eden/Desktop/platzi/node2020/components/message/store.js:31:37)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async /Users/eden/Desktop/platzi/node2020/components/message/controller.js:38:23
(node:69315) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:69315) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
No me ha funcionado con Mongo, creo que es mi operador de internet. pero lo estoy aplicando con firebase.
Pueden tambien hacer uso de la deconstruccion:
const { id } = req.params;
const { message } = req.body;
Vale. El problema de que .save() is not a function es por que find() te trae un array. Entonces usando findeOne() te soluciona el problema.
:gree_heart:
En ves de utilizar promesa en el “controller.js” utilize async y funciona practiamente igual pero con codigo mas entendible y corto.
Codigo con promesas
return new Promise(async (resolve, reject) => {
if (!id || !message) {
reject('Invalid date')
return false
}
try {
const result = await store.updateText(id, message)
resolve(result)
} catch (error) {
console.error(error, 'ha ocurrido un error')
}
})
Codigo con Async:
if (id && message) {
try {
const result = await store.updateText(id, message)
return result
} catch (error) {
console.error(error, 'ha ocurrido un error')
}
}
Algo que no explico el profesor y es que tenemos que tomar el id de un mensaje que este en mongodb… esto me tomo 1 dia en saberlo y era que le estaba pasando un id que no existia.
Entonces el findOne() se usa en casos tu quieras buscar solo un objecto que comparta el valor indicado.
Mas info aca:
https://masteringjs.io/tutorials/mongoose/find
Si alguien del Team Platzi está viendo esto, ojalá pudieran agregar un curso con Sequelize también, sería bueno.
recuerde podemos hacer desestructuración:
const { id } = req.params
const { text } = req.body
Desde la clase anterior se me rompió el código, alguien lo tiene completo para hacer la comparación de que me salte algún punto o coma, muchas gracias!!
WoW este curso esta super pero se me esta dificultando
Increíble hasta el momento
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?