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

1

Bienvenida y presentaci贸n del curso

2

Qu茅 es Node y c贸mo instalarlo

3

驴Qu茅 son y c贸mo se usan las peticiones HTTP?

4

M茅todos, cabeceras y estados

5

Cuerpo y query de la petici贸n

Crear un servidor HTTP en Javascript, y comenzar a escuchar y responder peticiones desde un cliente .

6

Crear un servidor HTTP desde NodeJS

7

驴C贸mo pueden venir las peticiones?

8

Recibir informaci贸n desde el cliente: Body y Query

9

Informaci贸n contextual: Leer las cabeceras

10

Tipos de respuesta: Vac铆a, plana, con datos y estructurada

11

Respuestas coherentes

12

Servir archivos est谩ticos

13

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

14

Conceptualmente: Rutas, controladores y bases de datos

15

Rutas y capa de red: Responsabilidades y l铆mites

16

Controladores: Definiendo la l贸gica de negocio

17

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

18

Tipos de Bases de Datos: Relacionales y No Relacionales

19

Crear y Configurar tu Base de Datos con MongoDB

20

MongoDB: Almacenar y leer datos

21

MongoDB: Actualizar datos

22

MongoDB: Consultar datos

23

MongoDB: Eliminar Datos

24

Gestionar conexiones a la base de datos desde la API

Uso de entidades para crear aplicaciones escalables

25

Escalando la arquitectura: M煤ltiples entidades

26

Relacionando nuestras entidades

27

C贸mo recibir ficheros desde NodeJS

28

Guardar el fichero en el servidor

Conocer el protocolo de websockets, e implementar comunicaci贸n cliente/servidor con SocketIO.

29

WebSockets: Qu茅 son, por qu茅 son interesantes y c贸mo usarlos

30

Manejo de Websockets con NodeJS

31

Conectar la API al servidor de WebSockets

Revisi贸n de lo aprendido, y pr贸ximos pasos

32

Revisi贸n y pr贸ximos pasos

33

Tips para escalar nuestro proyecto

A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

MongoDB: Actualizar datos

21/33
Recursos
placeholder

Aportes 41

Preguntas 6

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

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.

Ese error del await en el minuto 06:37 es buen铆simo

驴Ser铆a buena pr谩ctica utilizar async/await dentro de una promesa? 馃

He estado buscando informaci贸n y he encontrado esto:

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.

Creo que en Mongoose podemos encontrar un registro y actualizarlo en la misma petici贸n.
https://mongoosejs.com/docs/tutorials/findoneandupdate.html

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 馃挌

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?

Que bueno que le salio el error del async por fuera al profesor, no se si yo lo hubiese encontrado tan rapido

Si les aparece el siguiente error y no saben como eliminarlo aun si se les actualiza la informacion, se debe entonces eliminar el 鈥淩ES.SEND(鈥極K鈥)鈥, 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.

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,
};

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;
}

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.

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 鈥渜ue 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

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)
(Usenode --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铆

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
    
}

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!

Cuando lo intent茅. En lugar de actualizar el mensaje cre贸 uno nuevo. Lo solucion茅 cambiando la ruta patch por put

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 鈥渃ontroller.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.

<h3>Creo que el metodo find te busca aquellos que comparten el mismo valor. Obviamente un ID tiene un valor unico, por eso retorna uno nomas.</h3>

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