Alfredo Mendoza Fuentes
@amefu
Lima, Peru
@amefu
Lima, Peru
Alfredo Mendoza Fuentes@amefu
Al ejecutar el docker-compose mostrado en el video, todo ejecuta bien, pero menos el mongo-express, que valores necesito actualizar en el manifiesto ?
Alfredo Mendoza Fuentes@amefu
Me encuentro siguiendo el curso por windows y he tenido este inconveniente a la hora de cargar el archivo .js, me indica que no estoy autorizado, alguna idea de que configuración a nivel del servicio o de mongo tenga que realizar.
Mi base de datos se llama edbase
Alfredo Mendoza Fuentes@amefu
1<!-- <div class="wrapper" *ngIf="showModal$ | async"> --> 2<div class="wrapper"> 3 <div class="new-task"> 4 <form [formGroup]="newTask" (ngSubmit)="saveTask()"> 5 6 <div class="form-input"> 7 <label>Titulo</label> 8 <input formControlName="order" type="text"> 9 </div> 10 11 <ng-container formArrayName="item" 12 *ngFor="let field of getItems();let i = index" > 13 <!-- *ngFor="let field of formItemsGroup$ | async;let i = index" > --> 14 15 <div class="form-input" 16 [formGroupName]="i"> 17 <label>{{field?.value?.key}}</label> 18 <input formControlName="value" type="text"> 19 </div> 20 21 </ng-container> 22 23 <div class="form-input"> 24 <button class="btn-primary">Guardar</button> 25 <button (click)="cancel()" class="btn-default">Cancelar</button> 26 </div> 27 </form> 28 </div> 29</div>
1.wrapper{ 2 position: fixed; 3 width: 100%; 4 height: 100%; 5 z-index: 1; 6 top:0; 7 right:0; 8 background-color: rgba(0,0,0,.3); 9 display: flex; 10 align-items: center; 11 justify-content: center; 12 align-content: center; 13} 14 15.new-task{ 16 width: 650px; 17 padding: 1rem; 18 min-height: 400px; 19 background-color: #fff; 20 box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; 21} 22 23.new-task form{ 24 display: flex; 25 gap: .5rem; 26 flex-direction: column; 27} 28 29.form-input{ 30 display: flex; 31 flex-direction: column; 32} 33 34.form-input input, .form-input textarea{ 35 border:solid 2px #DFE1E6; 36 background-color: #FAFBFC; 37 min-height: 40px; 38 border-radius: var(--border-radius); 39 padding: 0 .5rem; 40}
1import { Component, OnInit } from '@angular/core'; 2import { FormArray, FormControl, FormGroup } from '@angular/forms'; 3import { NewTaskService } from '@modules/task/services/new-task.service'; 4 5@Component({ 6 selector: 'app-new-task', 7 templateUrl: './new-task.component.html', 8 styleUrls: ['./new-task.component.css'] 9}) 10export class NewTaskComponent implements OnInit { 11 12 newTask:FormGroup = new FormGroup({}) 13 showModal$ = this.newTaskService.showModal$ 14 15 constructor( 16 private newTaskService:NewTaskService 17 ) { } 18 19 ngOnInit(): void { 20 this.newTask = new FormGroup( 21 { 22 order: new FormControl(''), 23 item: new FormArray([ 24 new FormGroup( 25 { 26 key: new FormControl('Precio'), 27 value: new FormControl('') 28 } 29 ), 30 new FormGroup( 31 { 32 key: new FormControl('Observacion'), 33 value:new FormControl('') 34 } 35 ), 36 ]), 37 } 38 ) 39 } 40 41 getItems():any { 42 console.log(this.newTask.get('item')) 43 const list = this.newTask.get('item') as FormArray 44 return list.controls 45 } 46 47 saveTask():void { 48 console.log(this.newTask.value) 49 } 50 51 cancel():void { 52 this.newTaskService.setShow(false) 53 } 54 55} 56
1import { Injectable } from '@angular/core'; 2import { BehaviorSubject } from 'rxjs'; 3 4@Injectable({ 5 providedIn: 'root' 6}) 7export class NewTaskService { 8 9 _showModal$ = new BehaviorSubject(false) 10 showModal$ = this._showModal$.asObservable() 11 12 constructor() { } 13 14 public setShow(flag:boolean){ 15 this._showModal$.next(flag) 16 } 17} 18
En task-page.html agregar al final
<app-new-task></app-new-task>
En task.module.ts no olvidar importar el
ReactiveFormsModule
Alfredo Mendoza Fuentes@amefu
Les dejo las partes de código para copiar y pegar
1<app-header></app-header> 2<div class="task-columns"> 3 <app-column [cardTitle]="item.label" [dataCards]="item.list" 4 *ngFor="let item of groupCard"> 5 </app-column> 6</div>
1.imagen { 2 width: 200px; 3 height: 200px; 4 background-color: rgb(205, 205, 255); 5} 6 7.task-columns { 8 position: relative; 9 /* background-color: rgba(255, 0, 0, 0.103); */ 10 display: flex; 11 flex-wrap: wra; 12 flex-direction: row; 13 gap: .25rem; 14 overflow-x: auto; 15 min-height: 500px; 16 padding: 0 1rem; 17} 18 19.cdk-drag-placeholder { 20 position: relative; 21 opacity: 1; 22 display: block; 23 width: 20rem; 24 transition: all ease 230ms; 25 cursor: move; 26 border-radius: 15px; 27} 28 29.cdk-drag-placeholder:after { 30 content: ""; 31 position: absolute; 32 width: 100%; 33 height: 100%; 34 background-color: #DFDEDC; 35 border-radius: 15px; 36 top: 0; 37 left: 0; 38} 39 40.cdk-drag-preview { 41 display: block; 42 width: 500px; 43 transition: all ease 150ms; 44 border-radius: 15px; 45 background-color: transparent; 46} 47 48.cdk-drag-preview { 49 background-color: var(--color-secondary); 50 transition: all ease 150ms; 51 box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; 52} 53 54 55/* Animate items as they're being sorted. */ 56 57.cdk-drop-list-dragging .cdk-drag { 58 transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 59} 60 61 62/* Animate an item that has been dropped. */ 63 64.cdk-drag-animating { 65 transition: transform 300ms cubic-bezier(0, 0, 0.2, 1); 66}
1 groupCard:Array<any> = [] 2 3 //para destruir las subscripciones 4 listObservables$:Array<Subscription> = [] 5 6const observer1$ = interval(1000).subscribe(res => { 7 console.log('Corriendo') 8 }) 9 10 this.listObservables$ = [observer1$] 11 12 console.log(this.groupCard.length) 13 14 this.groupCard = [ 15 { 16 label: 'Hola Mundo', 17 color: 'tomato', 18 list: [ 19 { 20 order: 'Como instalar Angular', 21 items: [ 22 { 23 key:'price', 24 value: 152 25 }, 26 { 27 key:'time', 28 value: 152 29 }, 30 { 31 key:'author', 32 value: { 33 name: 'Leifer Mendez', 34 avatar: '' 35 } 36 } 37 ] 38 } 39 ] 40 }, 41 { 42 label: 'Nuevos', 43 color: 'tomato', 44 list: [ 45 { 46 order: 'Como instalar Angular', 47 items: [ 48 { 49 key:'price', 50 value: 152 51 }, 52 { 53 key:'time', 54 value: 152 55 }, 56 { 57 key:'author', 58 value: { 59 name: 'Leifer Mendez', 60 avatar: '' 61 } 62 } 63 ] 64 } 65 ] 66 } 67 ] 68
1:host { 2 display: block; 3} 4 5.column { 6 padding: .5rem; 7 width: 20rem; 8 justify-content: space-between; 9} 10 11.column .circle { 12 width: 15px; 13 height: 15px; 14 border-radius: 30px; 15} 16 17.column .label-column { 18 gap: .5rem 19} 20 21.column .name { 22 font-weight: 500; 23} 24 25.column .number { 26 font-weight: 400; 27 opacity: .8; 28} 29 30.cdk-drag-placeholder { 31 position: relative; 32 opacity: 1; 33 display: block; 34 width: 100%; 35 transition: all ease 230ms; 36 cursor: move; 37 border-radius: 15px; 38} 39 40.cdk-drag-placeholder:after { 41 content: ""; 42 position: absolute; 43 width: 100%; 44 height: 100%; 45 background-color: #DFDEDC; 46 border-radius: 15px; 47 top: 0; 48 left: 0; 49} 50 51.cdk-drag-preview { 52 display: block; 53 width: 500px; 54 transition: all ease 150ms; 55 border-radius: 15px; 56 background-color: transparent; 57} 58 59.cdk-drag-preview .card { 60 transition: all ease 150ms; 61 transform: rotate(3deg); 62 box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; 63}
1<div class="column display-flex"> 2 <div class="label-column display-flex"> 3 <span class="circle" [style.backgroundColor]="'red'"></span> 4 <span class="name"> 5 {{ cardTitle }} <span class="number">({{dataCards.length}})</span> 6 </span> 7 </div> 8 <div class="label-column display-flex"></div> 9</div> 10 11<div class="column"> 12 <app-card cdkDrag 13 [idOrder]="card.order" 14 [items]="card.items" 15 *ngFor="let card of dataCards" > 16 </app-card> 17</div>
1 // 5.4 2 @Input() dataCards:Array<any> = [] 3 @Input() cardTitle!:string 4
1:host { 2 display: block; 3} 4 5.card { 6 background-color: white; 7 border-radius: 3px; 8 margin-bottom: 1rem; 9 min-height: 100px; 10 padding: .75rem 11} 12 13.card .title { 14 font-weight: 600; 15} 16 17.card .body { 18 list-style: none; 19 margin: 0; 20 padding: 0; 21 display: flex; 22 flex-direction: column; 23 gap: .35rem 24} 25 26.card .body li { 27 display: flex; 28 gap: .25rem; 29 font-size: 90%; 30} 31 32.card .body li span { 33 font-weight: 400; 34} 35 36.card .avatar-small { 37 width: 20px; 38 height: 20px; 39 border-radius: 5px; 40 object-fit: cover; 41}
1<div class="card"> 2 <div class="title"> N° {{idOrder}}</div> 3 <ul class="body"> 4 <ng-container *ngFor="let item of items"> 5 6 <li *ngIf="['price','time'].includes(item.key)"> 7 <i class="uil" [ngClass]="{ 8 'uil-credit-card':item.key == 'price', 9 'uil-clock':item.key == 'time' 10 }"></i> 11 <span>{{item.value}}</span> 12 </li> 13 <li *ngIf="['author'].includes(item.key)" > 14 <img class="avatar-small" [src]="item.value.avatar" alt=""> 15 <span>{{item.value.name}}</span> 16 </li> 17 18 </ng-container> 19 20 </ul> 21</div>
1 @Input() idOrder:string|number = 0 2 @Input() items:Array<any> = []
Alfredo Mendoza Fuentes@amefu
Profesor una duda, en el ejemplo realizado cuando se crea un .row, no se supone que los .col que debe contener el row, deben de dar la suma = a 12 ?
1 <div class="container"> 2 <div class="row"> 3 <div class="col-sm-6 col-md-4 col-lg 6 col-xl-10 bg-primary border">1</div> 4 <div class="col-sm-6 col-md-4 col-lg 6 col-xl-1 bg-primary border">2</div> 5 <div class="col-sm-12 col-md-4 col-lg 6 col-xl-1 bg-primary border">3</div> 6 </div> 7 </div>
Por ejemplo para el md marca la cifra correcta, para el xl igual, pero en sm (24) y en lg(18)
Alfredo Mendoza Fuentes@amefu
product.js
1const menu = [ 2 {id:100,name:'Papa Fritas', price:100}, 3 {id:200,name:'Hamburguesa Especial', price:50}, 4 {id:300,name:'Hamburguesa Mixta', price:40}, 5 {id:400,name:'Pizza', price:80}, 6 {id:500,name:'Soda', price:10}, 7] 8
index.js
1 2 3const usuario={nombre:'Alfredo', edad:'25', deuda:0} 4let pedidoUser = [] 5let ganancias = 0 6 7//Lista de los productos del menu 8const vermenu = () => { 9 console.log("ID - MENU - PRECIO") 10 menu.forEach(carta => console.log(`Id: ${carta.id} Nombre:${carta.name} Precio:${carta.price}`)) 11 return '' 12} 13 14//Formulario para realizar una orden 15const pedirProducto = codigo => { 16 while(codigo === null || codigo === undefined){ 17 codigo = prompt("Digite el codigo") 18 } 19 20 const ProductValid = menu.find(prod => prod.id === parseInt(codigo)) 21 22 23 if(!ProductValid) 24 { 25 alert("Digite un codigo de producto valido") 26 pedirProducto() 27 } 28 else{ 29 alert(`Has pedido una ${ProductValid.name} de S/.${ProductValid.price} se agregara a tu cuenta`) 30 pedidoUser.push(ProductValid) 31 32 let newpedido = prompt('Desea seguir ordenando ? Responsa si ó no ') 33 if(newpedido === "si") 34 { 35 pedirProducto() 36 } 37 else{ 38 verPedido() 39 } 40 } 41} 42//Método para ver los pedidos realizados 43const verPedido = () => pedidoUser 44 45vermenu() 46 47const calcularCosto = () => { 48 let costo = 0 49 pedidoUser.forEach(prod => costo+= prod.price) 50 usuario.deuda = costo 51 return usuario.deuda 52} 53 54const reporteVentas = () => `El día de hoy se ha ganado S/.${ganancias}` 55 56const pagarPedido = () => { 57 let monto 58 59 do { 60 monto = parseInt(prompt("Ingrese la cantidad de dinero a pagar")) 61 } while (monto <0 || isNaN(monto) ) 62 63 switch(true) 64 { 65 case (monto === 0): 66 console.log('No puedes pagar con 0 soles') 67 break; 68 case (monto > usuario.deuda): 69 let vuelto = (monto - usuario.deuda).toFixed(2) 70 alert(`Su deuda es de S/.${usuario.deuda} has pagado con S/.${monto} su vuelto es de S/.${vuelto}`) 71 ganancias+= usuario.deuda 72 usuario.deuda = 0 73 break 74 case (monto === usuario.deuda): 75 alert(`Su deuda es de S/.${usuario.deuda} Has pagado con S/.${monto} no hay vuelto`) 76 ganancias+= usuario.deuda 77 usuario.deuda = 0 78 break 79 case (monto < usuario.deuda): 80 alert('El dinero no te alcanza para cancelar tu deuda') 81 break 82 default: 83 alert('No tienes nada por pagar') 84 } 85} 86 87//Finaliza el pedido y se encarga de realizar el cálculo y cobro 88const finalizarPedido = () => { 89 calcularCosto() 90 pedidoUser = [] 91 do { 92 pagarPedido() 93 } while (usuario.deuda > 0); 94}
Alfredo Mendoza Fuentes@amefu
Como sabemos en nuestro método recibimos un parámetro de tipo genérico el cual tiene por nombre socialNetwork
, y para este caso lo declaramos como el tipo de clase SocialNetwork
dentro de la variable socialNetworkItem
, más adelante definimos una condicional para identificar si el objeto pertenece al de tipo SocialNetworkWithGroups
.
1 public string GetSocialNetworkStats<T>(T socialNetwork) 2 { 3 var socialNetworkItem = socialNetwork as SocialNetWork 4 5 if (socialNetworkItem is SocialNetworkWithGroups) 6 { 7 .... 8 } 9 return ... 10 }
Este procedimiento me llevo a pensar una manera de detectar el tipo de objeto que se esta recibiendo sin tener que declararlo directamente socialNetworkItem = socialNetwork as SocialNetWork
, en mi caso para evitar demasiadas declaraciones cuando se tengan distintos tipos. De tal forma que en mi búsqueda encontré las siguientes opciones para realizarlo.
De esta forma solo logre detectar el tipo, más no minificar la declaración para el respectivo tipo del objeto, puesto que una vez detectado, si pertenece a un tipo específico tendré que declarar dentro de la condicional al tipo que pertenece, aún no se acerca a lo que busco.
1 Type tipo = typeof(T); 2 3 if (tipo == typeof(SocialNetworkWithGroups)) 4 { 5 Console.WriteLine("Es una red social con grupos"); 6 } 7 else if (tipo == typeof(SocialNetwork)) 8 { 9 Console.WriteLine("Es una red social"); 10 }
Con esta otra forma evitamos la declaración de un objeto Type
para identificar el tipo de dato que estamos recibiendo en nuestro parámetro, mediante el método .GetType()
, adicionalmente esta opción tiene algo que la distingue de las opciones 1 y 3, que estaré explicando luego. La contra con esta opción es que nuevamente nos topamos con la necesidad de tener que declarar el tipo de dato al que pertenece una vez pasada la condicional, es una opción pero no la que deseo.
1 if (socialNetwork.GetType() == typeof(SocialNetwork)) 2 { 3 Console.WriteLine("Es una red social"); 4 } 5 else if (socialNetwork.GetType() == typeof(SocialNetworkWithGroups)) 6 { 7 Console.WriteLine("Es una red social con grupos"); 8 }
La última de todas es volver al inicio, así es, pero esta vez sin la necesidad de tipar la declaración del tipo de objeto luego de pasar la condición, de esta forma:
1 if (socialNetwork is SocialNetworkWithGroups sng) 2 { 3 Console.WriteLine($"{sng.Name} Es una red social con grupos"); 4 } 5 else if (socialNetwork is SocialNetwork sn) 6 { 7 Console.WriteLine($"{sn.Name} Es una red social"); 8 }
Logrando así declarar el tipo de objeto al que pertenezca e identificarlo mediante la misma condicional, obviando así la declaración antes o después que alguna condicional se cumpla.
1 var socialNetworkItem = socialNetwork as SocialNetWork 2 3 var socialNetworWithGroupItem =socialNetwork as SocialNetworkWithGroups 4
Respecto a la característica que comparten las opciones 2 y 3, es el orden de la condicional, como se vio en esta sesión, nuestra clase SocialNetworkWithGroups
hereda de SocialNetwork
, por lo cual en las opciones mencionadas, si la primera de nuestras condicionales se igual a la clase de la cual se esta heredando y luego le siguen otras clases que heredan de esa misma tendremos el siguiente resultado.
1//Digamos que el socialNetwork que se envía como parámetro es de tipo WithGroups: 2 3 if (socialNetwork is SocialNetwork sn) //Esto es verdadero 4 //se cumple la condicional 5 else if (socialNetwork is SocialNetworkWithGroups sng) //Esto también 6 //No llega hasta aquí 7 else if (socialNetwork is SocialNetworkWithGroups2 sng2) 8 ...
Esto sucede debido al factor de la herencia, es por ello que en la condicional, las clases que heredan de la principal deben de colocarse antes de esta, para que puedan ser evaluadas.
Ahora con las declaración de las variables ya simplificadas, en caso que tenga más clases que hereden de SocialNetwork
obtendre un conjunto anidado de condicionales
1 if (socialNetwork is SocialNetworkWithGroups stypefour) 2 ..... 3 else if (socialNetwork is SocialNetworkWithGroupsThree stypethree) 4 ..... 5 else if (socialNetwork is SocialNetworkWithGroupsTwo stypetwo) 6 ..... 7 else if (socialNetwork is SocialNetworkWithGroupsTOne stypeone) 8 ..... 9 else if (socialNetwork is SocialNetwork sn) 10 .....
Mi consulta sería, cual podría ser una solución para evitar un fuerte anidado en ese tipo de situaciones. Si bien esta la alternativa de usar un switch, existe algo más optimizado ? Por ejemplo algo para detectar el tipo de dato directamente sin tener que pasar por demasiadas validaciones.
Alfredo Mendoza Fuentes@amefu
Presente un problema con la librería lxml empleando pycharm en Windows
Al parecer se requiere hacer la instalación directamente en la terminal de windows
ejecutando un : pip install lxml
por si no les funciona esa solución aquí dejo 3 referencias para su solución en windows.
https://stackoverflow.com/questions/29440482/how-to-install-lxml-on-windows https://stackoverflow.com/questions/31750863/python-cant-find-or-install-lxml https://stackoverflow.com/questions/37653018/cant-install-lxml-on-python-3-5