curso node argumentos con yargs

seria interesante enviar a nuestra apliacacion argumentos por linea de comandos de una forma standar
algo asi:
[operacion] [nombre parametro] [valor parametro]

app listar --base 5

o incluso usando un alias

app listar -b 5

como hacemos esto facilmente? usando YArgs

lo buscamos en la pagina de npm
https://www.npmjs.com/package/yargs

y lo instalamos:

npm i yargs --save

esto hara que en nuestro archivo package.json
se agregue a la seccion de dependencias:

"dependencies": { "yargs": "^12.0.1" }


entonces ya podemos usar yargs en nuestra aplicacion
const argv=require('yargs') .command('listar','imprime por consola la tabla de multiplicar', { base:{ demand: true, alias: 'b' }, limite:{ alias:'l', default:10 } }).argv; console.log(argv.base); console.log(argv.limite);

en el codigo anterior estamos definiendo el command "listar" con 2 argumentos
base y limite, donde base es obligatorio y limite tiene un valor por default si
es que no se le asigna ninguno.

vamos a crear en nuestro multiplicar.js una function llamada listarTabla
en la que se le envie la base y el limite
y solo nos muestre el resultado por consola.

entonces nos quedaria asi

let listarTabla=(base,limite)=>{ return new Promise((resolve,reject)=>{ if(!Number(base)){ reject(`el valor introducido ${base} no es un numero`); return; } if(!Number(limite)){ reject(`el valor introducido ${limite} no es un numero`); return; } let data=''; for(let i = 1; i <= limite; i++){ data += ` ${base} x ${i} = ${base*i} \n`; } resolve(data); }); };

lo exportamos
module.exports = { crearArchivo,listarTabla }

y lo usamos en nuestra app principal

const { crearArchivolistarTabla } = require('./multiplicar');
let comando=argv._[0]; switch(comando){ case 'listar': listarTabla(argv.base,argv.limite) .then(data=>console.log(data)) .catch(e=>console.log(e)); break; case 'crear': crearArchivo(argv.base) .then(archivo=>console.log(`archivo creado: ${archivo}`)) .catch(e=>console.log(e)); break; default: console.log('el comando no existe'); }

curso node argumentos en linea de comando

process.argv es un arreglo que contiene los argumentos de linea de comando.
El primer elemento (process.argv[0]) contiene la ruta al ejecutable de node, el segundo elemento contiene el nombre del archivo javascript en ejecución. Los siguientes argumentos tienen los valores pasados por linea de comandos. .
process.argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
});
si en la consola ejecutamos:
args-by-console uno dos tres

obtendremos:
0: C:\Program Files\nodejs\node.exe 
1: c:\proyectos-node\03-bases-node\args-by-console.js
2: uno
3: dos
4: tres

curso node importar archivos file system


la documentacion de los archivos https://nodejs.org/dist/latest-v10.x/docs/api/fs.html
que se pueden importar que vienen ya en node.

const fs=require('fs');

let data='';
let base=2;

for(let i = 1; i <= 10; i++){
data += ` ${base} x ${i} = ${base*i} \n`;
}

fs.writeFile(`tabla-del-${base}.txt`, data, (err) => {
  if (err) throw err;
  console.log('The file has been saved!');
});

veamos ahora como importar archivos propios separando el proceso anterior de creacion de archivo escribiendolo en un archivo e importandolo desde otro:

creamos p.e: mutiplicar.js
donde tendremos


const fs=require('fs');



let crearArchivo=(base)=>{

    return new Promise((resolve,reject)=>{
     
      let data='';
  for(let i = 1; i <= 10; i++){
data += ` ${base} x ${i} = ${base*i} \n`;
  }

  fs.writeFile(`tabla-del-${base}.txt`, data, (err) => {
  if (err)
  reject(err);
  else
  resolve(`tabla-del-${base}.txt`);
});
     
    });

};
//aqui se definen las funciones globales que se quieren poner
//como disponibles a lo largo de la aplicacion
module.exports = {
crearArchivo
}


y lo llamamos desde app.js asi:

const { crearArchivo } = require('./multiplicar');
let base=6;

crearArchivo(base)
.then(archivo=>console.log(`archivo creado: ${archivo}`))
.catch(e => console.log(e));

vamos a agregar una validacion a nuestra funcion para que valide que la base sea un numero

al inicio de la Promise pondremos

if(!Number(base)){
      reject(`el valor introducido ${base} no es un numero`);
      return;//para que no continue ejecutando el resto de lineas
      }


curso node async y await

para simplificar la programacion usaremos async y await

entonces una funcion promesa como esta

let getNombre=()=>{
return new Promise( (resolve,reject)=>{
resolve('Israel');
})
}

se podria escribir asi:

let getNombre=async()=>{
  return 'ISrael';
}

donde lo que se retorna es nuestro resolve, por lo que la respuesta se seguiria tratando como en el caso de la funcion promesa

getNombre().then(nombre=>{
console.log(nombre);
})


todo error que se genere en la funcion async sera atrapada en la seccion catch de la llamada

let getNombre=async()=>{
  undefined.nombre; // error generado adrede a modo de ejemplo
  return 'ISrael';
}

getNombre().then(nombre=>{
console.log(nombre);
}).catch(error=>{
   console.log('Ha ocurrido un error', error);
})

si se quiere generar un error con un mensaje personalizado usaremos la clase Error y la lanzaremos


let getNombre=async()=>{
  throw new Error('el nombre no fue encontrado'); // error generado adrede a modo de ejemplo
  return 'ISrael';
}


AWAIT (se usa dentro de una funcion de tipo async)

sirve para hacer una llamada a una funcion asincrona pero no continua hasta que esta no le devuelva un resultado. Es como si simulara un comportamiento sincrono.


Entonces por ejemplo si queremos hacer una funcion saludo que necesita el nombre para armar el mensaje de saludo se podria usar el operador await, asi:

let saludo= async()=>{
  let nombre = await getNombre();
  return `hola ${nombre}`;
}

saludo().then(mensaje=>{
console.log(mensaje);
})



usando las funciones que habiamos hecho para getEmpleado y getSalario vamos a crear otra para obtener la informacion usando async y await, para ver como se simplifica todo

let empleados = [
{
  id:1,
  nombre:'luis'
},
{
  id:2,
  nombre:'maria'
},
{
  id:3,
  nombre:'javier'
}

];

let salarios = [
{
  empleado_id:1,
  salario:1000
},
{
  empleado_id:2,
  salario:2000
}
];

let getEmpleado=(id)=>{

    return new Promise( (resolve,reject)=>{
     
        let empleadoEncontrado=empleados.find(empleado => empleado.id === id);

        if(!empleadoEncontrado){
            reject(`no se encontro ningun empledo con id: ${id}`);
        }else{
            resolve(empleadoEncontrado);
        }

    });
  
}

let getSalario=(empleado)=>{
    return new Promise((resolve,reject)=>{
        let salarioEncontrado=salarios.find(salario => salario.empleado_id === empleado.id);

        if(!salarioEncontrado){
            reject(`no se encontro ningun salario para el empleado: ${empleado.nombre}`);
        }else{
            let respuesta={
                nombre:empleado.nombre,
                salario: salarioEncontrado.salario
            };
            resolve(respuesta);
        }
    });
}



let informacion = async(id)=>{

    let empleado = await getEmpleado(id);

    let salario = await getSalario(empleado);

    return `El Salario de ${empleado.nombre} es de ${salario.salario} pesos`;
}




informacion(10).then(mensaje=>console.log(mensaje))
.catch(error=>console.log(error));

curso node promises promesas

vamos a usar ahora Promises, entonces tomaremos una funcion que habiamos hecho antes
y la transformaremos:

let getEmpleado=(id,callback)=>{
let empleadoEncontrado=empleados.find(empleado => empleado.id === id);

    if(!empleadoEncontrado){
    callback(`no se encontro ningun empledo con id: ${id}`);
    }else{
    callback(null,empleadoEncontrado);
    }

}


let getEmpleado=(id)=>{

    return new Promise( (resolve,reject)=>{
   
        let empleadoEncontrado=empleados.find(empleado => empleado.id === id);

        if(!empleadoEncontrado){
            reject(`no se encontro ningun empledo con id: ${id}`);
        }else{
            resolve(empleadoEncontrado);
        }

    });

}
internamente la promesa tiene 2 callbacks de exito y error: resolve y reject

entonces ahora podemos llamar a la funcion asi:

getEmpleado(3).then(empleado=>{
    console.log('Empleado hallado en la BD',empleado);
   
},error=>{
    console.log(error);
})


ahora hagamos una funcion que devuelva el salario de un empleado:

let getSalario=(empleado)=>{
    return new Promise((resolve,reject)=>{
        let salarioEncontrado=salarios.find(salario => salario.empleado_id === empleado.id);

        if(!salarioEncontrado){
            reject(`no se encontro ningun salario para el empleado: ${empleado.nombre}`);
        }else{
            let respuesta={
                nombre:empleado.nombre,
                salario: salarioEncontrado.salario
            };
            resolve(respuesta);
        }
    });
}


y lo llamariamos asi:

getEmpleado(3).then(empleado=>{

    return getSalario(empleado)

}).then(salario=>{
        console.log('Salario',salario);
},error=>{
    console.log(error);
})

y para simplificar el manejo del error (el manejo del error es para ambas promises)

getEmpleado(3).then(empleado=>{
    return getSalario(empleado)
}).then(salario=>{
    console.log('Salario',salario);
}).catch(error=>{
    console.log(error);
})


curso node callbacks

empecemos por las funciones callbacks mas simples
se ejecutan despues de x milisegundos:


setTimeout(function(){
console.log('soy un callback!')
}, 1000);

setTimeout(()=>{
console.log('soy un callback flecha!')
}, 2000);


ahora creemos otra que nos devuelve los datos de un usuario

let getUsuarioById = (id, myCallback)=>{

//supongamos que el sgt objeto es traido desde la BD
let usuario ={
  id:id,
      nombre:'israel',
      apellido:'bazan'
};

myCallback(usuario); //ejecutamos el callback devolviendo el objeto usuario


};

//aqui llamamos a la funcion principal pero en el 2do parametro
//como sabemos que es una funcion callback que devuelve un objeto lo recibimos
//en la variable rpta


getUsuarioById(10, (rpta)=>{
console.log('usuario encontrado:',rpta);
});


lo cual va a imprimir

usuario encontrado: {id:10,nombre:'israel', apellido: 'bazan'}

Que pasaria si la busqueda del usuario no es exitosa?
debemos informar que sucedio un error, para esto es comun agregar un parametro extra de retorno
que hace referencia a un posible error.

let getUsuarioById = (id, myCallback)=>{

//supongamos que el sgt objeto es traido desde la BD
let usuario ={
  id:id,
      nombre:'israel',
      apellido:'bazan'
};
   
    if(id<=0){
    myCallback(`el usuario con id: ${id} no existe`);
    }else{
    myCallback(null,usuario);
}



};

getUsuarioById(10, (error,rpta)=>{
if(error){
   console.log(rpta);
}else{
console.log('Usuario encontrado:', rpta);
}

})



curso node funciones de flecha

la siguiente funcion

function sumar(a,b){
return a+b;
}

puede escribirse asi

let sumar=(a,b)=>{
     a+b;
}

o incluso asi:

let sumar=(a,b)=>a+b;

debido a que solo posee una linea de codigo.

si la funcion tiene un solo parametro

let duplicar=(a)=>a*2;

este puede ir sin parentesis 

let duplicar=a=>a*2;



Tambien podriamos modificar la sgt clase:

let profe = {
nombre : 'israel',
apellido : 'bazan',
/*getNombreCompleto : function(){
return `${this.nombre} ${this.apellido}`;
} */
    getNombreCompleto : () =>{
return `${this.nombre} : ${this.apellido}`;
} 

}; 

el problema aqui cuando querramos imprimir

console.log(profe.getNombreCompleto());

es que nos va a imprimir undefined  this.nombre y this.apellido

ya que this dentro de una funcion flecha hace referencia al contexto externo de la clase.

entonces para seguir usando this, debemos hacerlo asi:

getNombreCompleto () {
return `${this.nombre} : ${this.apellido}`;

curso node asignacion por destructuring/desestructuracion


permite asignar valores desde las propiedades de un objeto
a una serie de variables

por ejemplo supongamos que tenemos el siguiente objeto

let profe = {
nombre : 'israel',
apellido : 'bazan',
getNombreCompleto : function(){
return `${this.nombre} ${this.apellido}`;
}
};

y queremos tener un par de variables que hagan referencia al nombre y apellido.

esto lo lograriamos asi:

let nombre = profe.nombre;
let apellido = profe.apellido;

sin embargo obtendriamos el mismo resultado haciendo la asignacion por destructuring en una sola linea, asi:

let {nombre,apellido}=profe;

notar que en las llaves tenemos que poner el mismo nombre de los atributos del objeto.
Si quisieramos usar otros nombres se hace asi:

let {nombre:name,apellido}=profe;


curso node template literales



let nombre='superman';

let real='clark kent';

console.log(nombre+' es '+real);

console.log(`${nombre} es ${real}`);

nos sirve para concatenar cadenas


let a=nombre + ' es ' +real;
let b=`${nombre} es ${real}`;

console.log(a===b);

si hacemos una comparacion estricta nos imprime true

tambien podemos usarlo para operaciones

console.log(`${12 + 4}`);

imprimira 16

o incluso llamar a una funcion

function getNombre(){
return `${nombre} es ${real}`;
}

console.log(`${getNombre()}`);

lo que imprimira
superman es clark kent

curso node let y var

var

permite declarar la misma variable varias veces y no contempla ambitos de uso, tiene un alcance global a lo largo del programa

entonces el sgt codigo

var a=1;

if(true){
var a=2;
}
console.log(a);

imprimira

2


en cambio, LET no permite declarar varias veces una misma variable en el mismo ambito.

por lo que el sgt codigo:

let a=1;

if(true){
let a=2;
}
console.log(a);

imprimira 1

otro ejemplo de VAR...


for(var i=0;i<3;i++)
{
console.log(`valor= ${i}`);
}
console.log(i);


imprimira
0
1
2
3

en cambio

for(let i=0;i<3;i++)
{
console.log(`valor= ${i}`);
}
console.log(i);

nos dara un error pues i es undefined

si declaramos i antes del for

let i;
for(let i=0;i<3;i++)
{
console.log(`valor= ${i}`);
}
console.log(i);

imprimiria

0
1
2

undefined

pues i no ha sido inicializado con ningun valor.

entonces

let i=0;
for(let i=0;i<3;i++)
{
console.log(`valor= ${i}`);
}
console.log(i);

imprimiria

0
1
2
0




let a=10;

function cambiar(){
   a=a+10;
}

cambiar();

console.log(a);

imprimira 20


curso node nodemon

sirve para mantener escuchando por los cambios de un programa y lo ejecuta ni bien detecta que se ha guardado alguno.

lo instalamos asi:

node install -g nodemon


luego si quisieramos ejecutar un programa ingresariamos:

nodemos app.js

y listo. el proceso se quedara escuchando por nuevos cambios.
Si quisieramos darlo de baja ctrl+C.

curso node ciclo de vida de un proceso

Si tuviesemos el siguiente codigo:

console.log(`inicio`);

setTimeout(function(){
console.log(`primera function`);
}, 3000);
setTimeout(function(){
console.log(`segunda function`);
}, 0);
setTimeout(function(){
console.log(`tercera function`);
}, 0);

console.log(`fin`);

La salida seria

inicio
fin
segunda function
tercera function
primera function

porque????

node lo primero que hace es crear un main()en la cola de procesos
entonces
agrega a esta la primera sentencia
console.log.("inicio") y la ejecuta.

luego toma el bloque
setTimeout(function(){
console.log(`primera function`);
}, 3000);
y lo coloca tambien en la lista de procesos, la registra pero no la ejecuta
entonces la mueve a la pila de node apis.
hace los mismo con el segundo y tercer bloque SetTimeout

finalmente coloca la ultima sentencia console.log('fin') y como no es asincrona la ejecuta.
como no hay mas sentencias el metodo main termina()

mientras tanto el tiempo pasa y el 2do bloque ya esta listo para ejecutarse pero no se envia a la pila de procesos sino a la cola de callbacks, asi tambien el 3er bloque y el 1ero que era el que tenia mas segundos de espera.

ahora

node va a tomar el proceso que termino primero y lo llevara a ejecutar en la lista de procesos, y asi sucesivamente

curso node hola mundo

creamos una carpeta y adentro un archivo llamado app.js

let nombre='israel';

console.log(` hola ${nombre}`);

(la linea anterior es similar a escribir console.log('hola '+nombre);
pero vamos a preferir usar los literales entre backticks `` , a esta forma se le conoce como Template Strings o plantillas de cadenas de texto)

lo ejecutamos desde una consola dentro de la carpeta

node app.js

o tambien node app (sin la extension .js)

tambien podemos escribir el programa anterior asi:

function saludar(nombre)
{
let saludo=`Hola ${nombre}!`;
return saludo;
}

let saludo=saludar('israelito');

console.log(saludo);


nota:

si escribimos solamente node y damos enter, el proceso de interpretacion de node se ejecuta permanentemente, entonces, podemos escribir las sgts lineas
let a=10;(enter)
let b=25; (enter)
a+b (enter)
y se mostrara
35



curso node conceptos iniciales

es un lenguaje de backend
-tenemos acceso a los archivos de la maquina, a los procesos y a la informacion del SO

corre sobre el motor v8 de google, es un engine escrito en c++ traduce javascript en lenguaje maquina


que se puede hacer con node?

-uso de sockets para una comunicacion real cliente servidor
-subir archivos simultaneamente
-creacion de servicios REst
-conexion a Base de datos
-etc

este basado en un modelo de manejo eventos de entrada/salida no bloqueantes.
(Node uses an event driven non blocking I/O Model)
es decir se va a llamar simultaneamente a multiples procesos para acortar el tiempo
de respuesta.


laravel 5.6 envio de mails

la configuracion se realiza en el archivo config/mail.php
donde podemos setear los datos del usuario al enviar un correo

'from' => [
        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
        'name' => env('MAIL_FROM_NAME', 'Example'),
    ],


los datos de conexion del servidor de correo los va a tomar
del archivo de entorno .env

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null


el host por default es mailtrap que es un entorno para desarrolladores de testeo de mails.
vamos a la pagina https://mailtrap.io/ y nos registramos
AL registrarnos vamos a tener una casilla de correos Demo Inbox
si cleckeamos sobre ella nos motrara las credenciales de conexion


SMTP
Host: smtp.mailtrap.io

Port: 25 or 465 or 2525

Username: 076c14147f6715

Password: c1ba4b109f4323


de donde usaremos los valores de username y password para setearlos en .env


luego vamos al controller donde se guarda un mensaje

y pegamos el sgt codigo

 Mail::send('emails.contact',['msg'=>$message],
          function($me) use ($message){
            $me->to($message->email,$message->nombre)->subject('tu mensaje ha sido recibido');
          }
        );

para lo cual previamente habremos creado la vista

views/emails/contact.blade,.php

vacia por el momento.

ahoa vamos y creemos un mensaje.

luego vayamos a nuestra cuenta en mailtrap

y veremos en nuestra casillla algo asi:





tu mensaje ha sido recibido
From: Example <hello@example.com>
To: israelito <israelbazan76@gmail.com>





linux ubuntu mint actualizar chrome

 desde una terminal: $ sudo apt update $ sudo apt install google-chrome-stable