No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Reg铆strate

Comienza en:

3D
4H
45M
20S

Uso de *ngFor

12/22
Recursos

Al igual que con un聽If, Angular permite聽iterar聽un array de n煤meros, de cadenas de caracteres o de objetos usando聽鈥*ngFor鈥.Si tienes en tu componente un array de datos:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  myArray: string[] = [
    'Platzi',
    'es',
    'genial!'
  ];
}

Puedes mostrar cada elemento iterando el array en un elemento HTML:

<ul>
    <li *ngFor="let str of myArray">
        {{ str }}
    </li>
</ul>

El聽*ngFor聽crea una variable temporal llamada聽str聽(o el nombre que m谩s te guste) que contiene cada valor de聽myArray. Finalmente, utilizando una interpolaci贸n, muestras el valor de聽str.Quedando tu HTML de la siguiente manera:

<ul><li>Platzi</li><li>es</li><li>genial!</li></ul>

脥ndice de iteraci贸n

  • ngFor聽tambi茅n cuenta con un聽铆ndice聽con el n煤mero de iteraciones. Puedes acceder a este n煤mero agregando al聽ngForindex as i聽de la siguiente manera:
<ul>
    <li *ngFor="let str of myArray; index as i">
        {{ i }}. {{ str }}
    </li>
</ul>

Cada iteraci贸n contiene una variable聽i聽con el 铆ndice que le corresponde. Iniciando desde cero, da como resultado:

<ul>
    <li>0. Platzi</li>
    <li>1. es</li>
    <li>2. genial!</li>
</ul>

Aporte creado por: Kevin Fiorentino (Platzi Contributor).

Aportes 63

Preguntas 6

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Array de emojis

emojis = [ '馃槀' , '馃惁', '馃惓','馃尞', '馃挌']

Hasta el momento este curso va ordenado, la verdad Nicol谩s explica de una manera que sinceramente se complementa muy bien con la documentaci贸n de Angular. 馃槂

驴Alguien m谩s est谩 pensando abandonar React por Angular? 馃槏

en el minuto 1:13

creo q hay un peque帽o error en cuanto a tipar el array, cuando usamos

names: string[] | number[] = [12, 'david'];

no significa q el array puede contener ambos valores si no que el array puede ser de strings o de numbers, es decir no se pueden mezclar por lo q el ejemplo es err贸neo.
Para que pueda contener ambos tipos debemos usar any

  • Agregu茅 una lista productos y precios:

Archivo: app.component.html

<h1>Reto 01: *ngFor</h1>
<h3>Cumplido</h3>
<label for="">Agregar art&iacute;culo</label>
<input type="text" required [(ngModel)]="newItem"><br>
<label for="">Agregar precio</label>
<input type="text" required [(ngModel)]="newPrice"><br>
<button (click)="addItem()">Add item</button>
<ul>
  <li *ngIf="items.length === 0">No hay art铆culos en existencia, puedes agregar m&aacute;s</li>
  <li *ngFor="let item of items; index as i">
    {{ i+1 }} - {{ item[0] }} ${{ item[1] }}.00
    <button (click)="deleteItem(i)">Delete</button>
  </li>
</ul>

Archivo: app.component.ts

items: any[] = [ ['Platano', 10], ['Manzana', 15], ['Aguacate', 30] ] //Reto *ngFor
  newItem = '' //Reto *ngFor
  newPrice = ''; //Reto *ngFor

addItem() {
    this.items.push([this.newItem, this.newPrice]);
    this.newItem = '';
    this.newPrice = '';
  }

  deleteItem(index: number) {
    this.items.splice(index, 1);
  }

Hice un sistema de inventario MUY B谩sico:

Angular es muy interesante馃榾

Prefiero dejar el *ngIf afuera de la lista (ul)

<ul>
  <li *ngFor="let name of names; index as i">
    {{i}} {{ name }}
    <button (click)="deleteName(i)">Delete</button>
  </li>
</ul>
<p *ngIf="names.length === 0">No hay nombres</p>

Uso de *ngFor

El *ngFor es otra de las estructuras de control en Angular, que nos sirve para iterar un arreglo de elementos o mas conocido como array.

Esta directiva permite renderizar cada elemento dentro de un array, puede ser un array de strings, enteros, fechas, etc. o de elementos mas complejos como un objeto que tiene distintas propiedades, veamos un ejemplo de uso de *ngFor

Primero definimos el arreglo de elementos en el app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
    /* Primero definimos en nuestro componte logico el arreagle de elementos */
    names: string[] = ['Nicolas', 'Julian', 'Susana', 'Andrea']; // <-- Arreglo names
}

Y despues con el databinding de la propiedad names (nuestro arreglo), lo iteramos con la directiva *ngFor en el app.component.html

<ul>
<!-- Iteramos el arreglo names -->
  <li *ngFor="let item of names; let i = index;"> <!-- i es el indice de la posicion del elemento en el array -->
    <label>{{ i }} - {{ item }}</label>
  </li>
</ul>

En nuestra aplicacion podremos ver algo como:

  • Nicolas
  • Julian
  • Susana
  • Andrea
<h1>*ngFor reto 1</h1>
<p><input type="text" required="true" #itemNameInput="ngModel" [(ngModel)]="newItem.name"/></p>
<p><input type="number" required="true" #itemPriceInput="ngModel" [(ngModel)]="newItem.price"/></p>
<p><button (click)="addItem()">Agregar</button></p>
<ul>
  <li *ngFor="let item of items; index as i">
    {{i}} - Producto: {{item.name}} Precio {{item.price}}
    <button (click)="deleteItem(i)">Eliminar</button>
  </li>
  <li *ngIf="items.length === 0">
    No se encuentran productos
  </li>
</ul>
  items: Item[] = [
    {name: 'Pan', price: 5},
    {name: 'Leche', price: 22},
    {name: 'Huevo', price: 32}
  ];

  newItem: Item = {name: "",price: 0};

  addItem() {
    this.items.push({name:this.newItem.name,price: this.newItem.price});
    this.newItem.name='';
    this.newItem.price=0;
  }

  deleteItem(index: number) {
    this.items.splice(index, 1);
  }

class Item {
  constructor(public name: String, public price: number) {}
}

Hola amigos鈥 para complementar el ejemplo de emojis realizado por Rony, he implementado un peque帽o ejemplo de teclado para agregar emojis a la lista.

TS

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  emojis: string[] = ['馃槀' , '馃惁', '馃惓','馃尞', '馃挌'];

  addEmoji(event: Event) {
    const element: HTMLElement = event.target as HTMLElement;
    this.emojis.push(element.textContent!);
  }
}

HTML

<h1>*ngFor</h1>
<ul>

  <p>Emojis Keyboard, click to add</p>
  <div class="emojiPicker">
    <div class="emojisList">
      <div class="emojiFrame" (click)="addEmoji($event)">馃槏</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃槝</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃ジ</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃槇</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃あ</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃懡</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃ズ</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃ケ</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃檲</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃惗</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃惐</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃</div>
      <div class="emojiFrame" (click)="addEmoji($event)">馃懇鈥嶐煉</div>
    </div>
  </div>
  <p>Emojis list</p>
  <li *ngFor="let item of emojis; index as i">
    {{item}} : {{i + 1}}
  </li>

</ul>

CSS

.emojiPicker {
  width: 308px;
  overflow: auto;
  border: 1px solid #0d8cfc;
  background-color: aliceblue;
  margin: 16;
  padding: 8;
  margin-bottom: 22px;
  border-radius: 22px;
  -webkit-box-shadow: 1px 1px 5px -1px rgba(0,0,0,0.75);
  -moz-box-shadow: 1px 1px 5px -1px rgba(0,0,0,0.75);
  box-shadow: 1px 1px 5px -1px rgba(0,0,0,0.75);
}
.emojisList{
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}
.emojiFrame{
  box-sizing: content-box;
  user-select: none;
  text-align: center;
  cursor: pointer;
  width: 30px;
  font-size: 21px;
  padding: 3px;
  margin: 3px;
  background-color: transparent;
  transform: scale(0.9);

  transition: background-color 0.2s, transform 0.1s;
}

.emojiFrame:hover{
  background-color: #0d8cfc;
}

.emojiFrame:active{
  background-color: #4babff;
  transform: scale(0.95);
}
<div>
  <p>Nombre del Empleado:{{nombre}}</p>
  <p>Edad:{{edad}}</p>  
  <p *ngIf="edad>=18">Es mayor de edad.</p>
  <table border="1">
    <tr>
      <td>Sueldos</td>
    </tr>
    <tr *ngFor="let sueldo of sueldos">
      <td>{{sueldo}}</td>
    </tr>
  </table>
</div>

//en app.component.ts
areastop5:string[]=[鈥楢ngular鈥,鈥業ngles鈥,鈥楪it鈥,鈥楶ython鈥,鈥楢WS鈥橾

<code> 

//en app.component.html
<h1>Top 5 Areas</h1>
<ul>
    <li *ngFor="let top5 of  areastop5;index as i ">{{i}} {{top5}}</li>
</ul>
<ul>

esto pude servir para hacer un todo con angular

La lista almacena objetos, el objeto simula ser un art铆culo, se puede agregar y eliminar art铆culos.

Archivo .html

<button (click)="addArticle()">Agregar</button>
<label>Codigo</label>
<input type="number" required min="1" max="10000" [(ngModel)]="newArticle.cod" />
<label>Nombre</label>
<input type="text" required [(ngModel)]="newArticle.art" />
<li *ngIf="articles.length == 0">Lista Vacia</li>
<ul *ngFor="let article of articles; index as i">
  <li>
    {{i+1}} :  {{article.cod}} - {{article.art}}
    <button (click)="deleteArticle(i)">Delete</button>
  </li>
</ul>

Archivo .ts

articles = [
    {
      cod: 123,
      art: 'Reloj'
    },
    {
      cod: 124,
      art: 'Celular'
    },
    {
      cod: 125,
      art: 'Tijera'
    },
  ]

  newArticle = { cod: 0, art: ''};


  addArticle() {
    console.log(this.newArticle.art);
    this.articles.push(
      {
        cod:this.newArticle.cod,
        art:this.newArticle.art
      }
    );
    this.newArticle.art = '';
    this.newArticle.cod = 0;
  }


  deleteArticle(index: number) {
    this.articles.splice(index,1);
  }
newName:  (string|number) =''

Algo tranqui

hice este peque帽o ejemplo por si alguien le interesa crear un peque帽o crud con listas y formularios.
https://github.com/MrRocklion/ejemploFormularioAngular

me encanta angular, vengo de aprender react y ya no se cual me gusta mas jajajjajajjajajajjajaja

Reto ngfor 馃憣
app.component.ts鈥

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  name = 'Pia';
  age = 42;
  myImg = 'https://source.unsplash.com/random';
  btnDisabled = true;
  persons=[{
     name: 'Pia',
     age : 45,
     avatar : this.myImg,
     emoji : '馃槀',
     phone_number: '3175120737',
     birthday: '04/06/1980'
  }]
  person={
    name: 'Pia',
    age : 45,
    avatar : this.myImg,
    emoji : '馃槀',
    phone_number: '3175120737',
    birthday: '04/06/1980'
 }

  newPerson={
    name: 'Nombre',
    age : 0,
    avatar : this.myImg,
    emoji : '馃槀',
    phone_number: '########',
    birthday: 'dd/mes/aa'
 }

  newName="";

  emojis = ['馃槀', '馃惁', '馃惓','馃尞', '馃挌'];

  toggleButton(){
    this.btnDisabled =  !this.btnDisabled;
  }

  increaseAge(){
    this.person.age +=1;
  }

  decreaseAge(){
    this.person.age -=1;
  }
  onScroll(event: Event){
    const element = event.target as HTMLElement;
    console.log (element.scrollTop);
  }
  changeName(event: Event){
    const element = event.target as HTMLInputElement;
    console.log (element.scrollTop);
    this.person.name= element.value;
  }
  addPerson(){
    this.persons.push(this.newPerson);
    this.newPerson = {
      name: 'Nombre',
      age : 0,
      avatar : this.myImg,
      emoji : '馃槀',
      phone_number: '########',
      birthday: 'dd/mes/aa'
   };
  }
  removePerson(i:number){
    this.persons.splice(i,1);
  }
}

app.component.html鈥

<h1>Personas (*ngFor Reto)</h1>
<p>Nombre:<input type="text" required [(ngModel)]="newPerson.name" ></p>
<p>Edad:<input type="text" required [(ngModel)]="newPerson.age" ></p>
<p>Emoji:<input type="text" disabled [(ngModel)]="newPerson.emoji" ></p>
<ul>
  <li *ngFor="let emoji of emojis">{{ emoji }} <button (click)="newPerson.emoji = emoji">Quiero este!</button></li>
</ul>
<p>Tel茅fono:<input type="text" required [(ngModel)]="newPerson.phone_number" ></p>
<p>Nacimiento:<input type="text" required [(ngModel)]="newPerson.birthday" >
<p><button (click)="addPerson()">Agregar persona</button></p>
<ul>
  <li *ngIf="persons.length === 0; else elseBlockPerson">No hay mas personas para mostrar</li>
  <ng-template #elseBlockPerson>
    <table>
      <thead>
        <tr>
          <th style="">No.</th>
          <th>Emoji</th>
          <th>Nombre</th>
          <th>Edad</th>
          <th>No. de tel茅fono</th>
          <th>Cumplea帽os</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let person of persons; index as i">
          <td>{{ i+1 }}</td>
          <td>{{ person.emoji }}</td>
          <td>{{ person.name }}</td>
          <td>{{ person.age }}</td>
          <td>{{ person.phone_number }}</td>
          <td>{{ person.birthday }}</td>
          <td><button (click)="removePerson(i)">Quitar</button></td>
        </tr>
      </tbody>
    </table>
  </ng-template>
</ul>

Resultado:

Array de sue帽os:

listaDeSuenios : string[] = ['Comprar un barco', 'Comprar un pez', 'Vender Plantas'];

y le agregu茅 esto

  <ul>
    <li *ngIf="listaDeSuenios.length === 0">No tienes sue帽os :(</li>
    <li *ngFor="let suenios of listaDeSuenios; index as i">
      {{i+1}}{{' '+suenios}}
      <button (click)="eliminarSuenio(i)">Eliminar</button>
    </li>
    <li *ngIf="listaDeSuenios.length >= 5">Te dicen Jos茅 el so帽ador</li>
  </ul>

  <span *ngIf="listaDeSuenios.length < 5">
    <input type="text" required [(ngModel)]="suenio">
    <button (click)="agregarSuenio()" >Agregar Nombre</button>
  </span>

Directiva ngFor


a directiva ngFor en Angular es una directiva de enlace de plantilla que permite iterar sobre una colecci贸n de datos y mostrar un elemento por cada elemento en la colecci贸n. La sintaxis b谩sica de ngFor es la siguiente:

<div *ngFor="let item of items">{{ item }}</div>

En esta sintaxis, items es una colecci贸n de datos, y item es una variable temporal que se establece para cada elemento en la colecci贸n. En cada iteraci贸n, el valor de item se asigna al siguiente elemento en la colecci贸n items.

Por ejemplo, si tienes una colecci贸n de nombres de frutas en tu componente de Angular y quieres mostrar un elemento por cada fruta en la lista, puedes usar ngFor de la siguiente manera:

<div *ngFor="let fruit of fruits">{{ fruit }}</div>

La directiva ngFor tambi茅n admite algunas caracter铆sticas avanzadas, como la obtenci贸n de un 铆ndice de iteraci贸n y la asignaci贸n de una clase CSS a un elemento en funci贸n de una condici贸n. Aqu铆 hay un ejemplo que muestra c贸mo usar estas caracter铆sticas:

<div *ngFor="let fruit of fruits; index as i; first as isFirst">
  <p [class.highlight]="isFirst">{{ i + 1 }}: {{ fruit }}</p>
</div>

En este ejemplo, se usa el 铆ndice de iteraci贸n i para mostrar un n煤mero de orden antes de cada fruta. Tambi茅n se usa una variable booleana isFirst para determinar si la fruta actual es la primera en la lista. Si isFirst es true, se aplica la clase CSS highlight a la etiqueta p
.

Reto Cumplido 鈥!

Una ligera modificaci贸n que har铆a para mejorar esta lista es que no podamos agregar elementos si el input est谩 vac铆o. Muy simple de hacer:

<button (click)="addName()" [disabled]="!(newName.length > 0)">Add name</button>

Vengo de Vue y siempre hab铆a escuchado cosas no muy 鈥渂uenas鈥 de Angular, pero la verdad me esta encantando!!!

Vengo de trabajar 2 a帽os con React y vaya que me estoy llevando una muy buena impresi贸n con Angular.

Este fue el ejercicio que realice con lo aprendido hasta ahora e investigando .

que increible curso, me encanta

No s茅 si me estoy adelantando un poco, pero la lista permite cargar elementos vac铆os, para que eso no suceda, primero a帽ad铆 required al input y le agregue un name, luego al bot贸n de carga de elementos lo condicione para que verifique si el input es v谩lido, y dependiendo de si es v谩lido (Renderiza el bot贸n) o no es v谩lido (Desaparece el bot贸n)

Quizas haya una forma mas eficaz pero fue la que se me ocurrio, les comparto mi ejemplo:

<h1>*ngFor</h1>
<input type="text" required #newNameInput="ngModel" [(ngModel)]="newName" />
<button (click)="addNewName()" *ngIf="newNameInput.valid === true">Add name</button>
<ul>
  <li *ngIf="names.length === 0" >No hay nombres</li>
  <li *ngFor="let name of names; index as i">
    {{ i }}{{ " " + name }}
    <button (click)="deleteName(i)" >Delete</button>
  </li>
</ul>

Un peque帽o aporte, adicion茅 un confirm para validar si el usuario realmente desea eliminar un nombre:

deleteName(index: number) {
if (confirm(鈥楢re you sure?鈥)) {
this.names.splice(index, 1);
}
}

Hice lista de tarea, y para agregar nuevas, reutilic茅 el mismo m茅todo, haciendo push al array de myTarea:

<h1>Lista de tareas</h1>
<input type=鈥渢ext鈥 required [(ngModel)]=鈥渘ewTarea鈥/>
<button (click)=鈥渁ddElem()鈥>Add tarea</button>
<li *ngIf=鈥渕yTarea.length === 0鈥>No hay tareas</li>
<li *ngFor=鈥渓et tarea of myTarea; index as i鈥>
{{i}} {{tarea}}
<button (click)=鈥渄eleteE(i)鈥>Delete</button>
</li>
<hr>

Yo lo que hice fue colocar que el usuario ingresara datos pero verificando que inicie con la inicial de la palabra sea el que marca ahi, ademas, que sea aleatorio, tanto la letra como a aspectos. Espero y les sirva.




  emojis: string[] = [ '馃槀' , '馃惁', '馃惓','馃尞', '馃挌'];
  emojisToAdd: string[] = ['馃挏', '馃悵', '馃悰', '馃'];
  newEmoji=''  


addEmoji() {
    this.emojis.push(this.newEmoji);
    const pos = this.emojisToAdd.findIndex(item => item == this.newEmoji);
    this.emojisToAdd = this.emojisToAdd.filter((item, index) => index != pos );
    this.newEmoji = '';
  }
  deleteEmoji(index: number) {
    this.emojisToAdd.push(this.emojis[index]); // con push no es suficiente para que el textarea se actualice, poruqe no estamos asignando directamente como aqu铆 abajo, curioso no ANGULAR
    this.emojisToAdd = this.emojisToAdd.filter((item) => item != '' );
    console.log(this.emojisToAdd);
    this.emojis.splice(index, 1);
  }
<h1> *ngFor </h1>
<textarea [(ngModel)]="emojisToAdd" value="{{emojisToAdd}}"></textarea><br>
<div *ngIf="emojisToAdd.length == 0">Enhorabuena {{person.name}}. Has a帽adido todos los emojis</div>
<input type="text" [(ngModel)]="newEmoji">
<button (click)="addEmoji()">Add Emoji</button>
<ul>
    <li *ngFor="let str of emojis; index as i">
        {{i}}. {{ str }}
        <button (click)="deleteEmoji(i)">Delete</button>
    </li>
</ul>

app.components.html

<input type=鈥渢ext鈥 [(ngModel)]=鈥渘ewLanguage鈥 >
<button (click)=鈥渁ddLanguage()鈥>add Language</button>
<ul>
<li *ngFor=鈥渓et Language of Languages; index as i鈥>
{{i}}:{{Language }}
<button (click)=鈥渄elete(i)鈥>Delete</button>
</li>
</ul>
<p *ngIf=鈥淟anguages.length === 0鈥>{{isEmpty()}}</p>

app.components.ts

Languages: string[] = [鈥楯avaScript鈥,鈥楶HP鈥,鈥楯ava鈥橾;
newLanguage= 鈥溾;

addLanguage(){
this.Languages.push(this.newLanguage);
this.newLanguage= "";
}

delete(index:number){
this.Languages.splice(index);
alert(鈥淓lemento eliminado鈥);
}
isEmpty(){
alert(鈥淟a lista esta vacia鈥);
}

Muy bien video.

El manejo de listas siempre es fundamental para la implementacion de la informacion por pantalla y las directivas de ngIf y ngFor siempre son muy utilizadas en los fomularios

Si tienen problemas con el else en el ngIf vayan al archivo tsconfig.json y cambien en angularCompilerOptions la propiedad

"strictTemplates":false

Gracias Nicol谩s tu explicaci贸n es muy clara, entendible y simple.

lo que mas me gusta de este curso, es que no solo estoy aprendiendo angular sino tambien HTML!!

app.component.html

<h1>LISTA DE ALUMNOS</h1>
<input type="text" [(ngModel)]="newAlumno" />
<button (click)="addAlumno()">Agregar</button>
<ul>
  <p *ngIf="alumnos.length === 0"> No hay alumnos, 隆Es hora de registrarlos!</p>
  <li *ngFor="let name of alumnos; index as i">
     {{i}}  {{name}}
     <button (click)="deleteAlumno(i)"> Eliminar</button>
  </li>
</ul>

app.component.ts

 alumnos: string[]=['Gustavo', 'Xiomara', 'Pedro', 'Lucho']
  newAlumno=''; 

  addAlumno () {
    this.alumnos.push(this.newAlumno); 
    this.newAlumno='';
  }

  deleteAlumno (index: number) {
    this.alumnos.splice(index,1);
  }

Muestra el bot贸n de 鈥淎dd Name鈥 煤nicamente cuando el input es distinto a vac铆o.

Muestra el bot贸n de 鈥淩emove Name鈥 煤nicamente cuando la lista tiene datos.

<button *ngIf="newName.trim() !== ''" (click)="addNameList()">Add Name</button>
<button *ngIf="names.length !== 0" (click)="removeNameList()">Remove Name</button>

Aqu铆 mi trabajo

// Nota.ts
export enum Tipo {
  REALIZADA="REALIZADA",
  PENDIENET="PENDIENTE",
  CANCELADA="CANCELADA"
}
export interface Nota {
  nombre: string;
  detalle: string;
  tipo: Tipo
}

//app.component.ts
import { Component} from '@angular/core';
import { Nota, Tipo } from './Nota';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public notas: Array<Nota> = [];
  public nuevaNota: Nota = {
    detalle: '',
    nombre: '',
    tipo: Tipo.PENDIENET
  }
  public notaSeleccionada: number | undefined = undefined;
  public datosValidos = true;
  get nombreEnum():Array<string>{
    return Object.keys(Tipo);
  }
  public agregarNota(index?:number){
    if(this.nuevaNota.detalle.trim() === '' || this.nuevaNota.nombre.trim() === '' || this.nuevaNota.tipo.trim() === ''){
      this.datosValidos = false;
      return;
    }
    this.datosValidos = true;
    if(index !== undefined){
      this.notas[index] = {...this.nuevaNota};
      this.vaciarNuevaNota();
      return;
    }
    this.notas.push(this.nuevaNota);
    this.vaciarNuevaNota();
  }
  public buscarNota(index: number): void{
    this.nuevaNota = {...this.notas[index]}
    this.notaSeleccionada = index;
  }
  public eliminarNota(index: number): void{
    this.notas.splice(index,1);
  }
  private vaciarNuevaNota(): void{
    this.nuevaNota = {
      detalle: '',
      nombre: '',
      tipo: Tipo.PENDIENET
    }
  }
}

<!-- app.component.html -->
<main>
  <section>
    <fieldset>
      <label for="nombre">Ingrese el nombre * </label>
      <input type="text" id="nombre" required name="nombre" [(ngModel)]="nuevaNota.nombre">
    </fieldset>
    <fieldset>
      <label for="tipo">Seleccione el tipo *</label>
      <select name="tipo" id="tipo" [(ngModel)]="nuevaNota.tipo">
        <option *ngFor="let tipo of nombreEnum" [value]="tipo">{{ tipo }}</option>
      </select>
    </fieldset>
    <fieldset>
      <label for="detalle">Escriba un detalle *</label>
      <textarea name="detalle" id="detalle" [(ngModel)]="nuevaNota.detalle" cols="30" rows="10"></textarea>
    </fieldset>
    <fieldset>
      <button (click)="agregarNota(notaSeleccionada)">Guardar</button>
    </fieldset>
    <fieldset>
      <p *ngIf="!datosValidos">Los campos con * son obligatorios</p>
    </fieldset>
  </section>
  <section>
    <table>
      <thead>
        <tr>
          <th>Nombre</th>
          <th>Detalle</th>
          <th>Tipo</th>
          <th>Acci贸n</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let nota of notas; index as i">
          <td>{{ nota.nombre }}</td>
          <td>{{ nota.detalle }}</td>
          <td>{{ nota.tipo}}</td>
          <td>
            <button (click)="eliminarNota(i)">Borrar</button>
            <button (click)="buscarNota(i)">Modificar</button>
          </td>
        </tr>
      </tbody>
    </table>
  </section>
</main>

Saludos

Esto fue lo que hice y pues me gusto esta forma de recorrer, eliminar, condicionar y agregar 馃槃

<h1>*ngFor</h1>
<input type="text" required [(ngModel)]="new_emoji">
<button (click)="add_emoji()">Add emoji</button>
<ul>
  <li *ngIf="emojis.length === 0"> Precauci贸n no hay emojis 馃ぇ</li>
  <li *ngFor="let emoji of emojis; index as i">
    {{i}} {{emoji}} <button (click)="delete_emoji(i)">Delete</button>
  </li>
</ul>
<br>

emojis: any[] = ['馃挬', '馃', '馃挏', '馃ケ']
new_emoji = '';

  add_emoji(){
    this.emojis.push(this.new_emoji);
    this.new_emoji='';
  }

  delete_emoji(index: number){
    this.emojis.splice(index, 1);
  }

<ul>
<li *ngFor=鈥渓et persona of personas; index as i鈥>
{{i}} {{persona.nombre}} {{persona.edad}}
</li>
</ul>

personas = [{nombre:鈥淐arlos鈥,edad:35},{nombre:鈥淒oris鈥,edad:38},{nombre:鈥淓dith鈥,edad:7}];

Algo muy interesante seria tambi茅n lograr que el boton de a帽adir este activo o desactivo dependiendo de si el input esta vac铆o o no. Les recomiendo intentarlo para mejorar la l贸gica de programaci贸n.
.
Les comparto mi soluci贸n:
.
HTML
.

<h1>ngFor</h1>
<ul>
  <li *ngFor="let unidad of unidades; index as id">
    id:{{id}} unidad:{{unidad}}
  </li>
</ul>

<input type="text" (keyup)="checkInput($event)" #inputUnidad="ngModel" [(ngModel)]="nuevaUnidad">
<button [disabled]="buttonDisabled" (click)="addUnidad()" >A帽adir Unidad</button>

.
compontent.ts:
.

  buttonDisabled = true;

  unidades: string[] = ['KW01', 'KW02', 'KW03'];
  nuevaUnidad: string = '';

  addUnidad() {
    if (this.nuevaUnidad === '') {
      return
    }else {
      this.unidades.push(this.nuevaUnidad);
    }
  }

  checkInput(event: Event) {
    const element = event.target as HTMLInputElement;

    if (element.value === '') {
      this.buttonDisabled = true;
    }else {
      this.buttonDisabled = false;
    }
  }

Yo realice mi taller con lista de mercado, colocando el nombre de lo que se debe comprar y una lista de la cantidad que se debe comprar

asi yo declare el array es lo mismo

names : array<string>=['noms','sasdda'];
o
names :string[]=['noms','sasdda'];

class Tool {
constructor(
public name: string,
public weight: number,
public weightUnit: string
) {}
}

tools: Tool[] = [
new Tool(鈥淢artillo鈥,1000,鈥淕R鈥),
new Tool(鈥淭aladro鈥,900,鈥淕R鈥),
new Tool(鈥淓smeriladora鈥,1,鈥淜G鈥 )
];

Array de art铆culos deportivos

app.component.ts

sportings: string[] = [鈥榖icycle鈥, 鈥榮occer ball鈥, 鈥榳eights鈥橾;
newArticle = 鈥樷;

addArticle( ) {
this.sportings.unshift(this.newArticle)
this.newArticle = 鈥樷;
}

deleteArticle(index: number) {
this.sportings.splice(index, 1);
}

app.component.html
<h1>Reto *ngFor</h1>
<input type=鈥渢ext鈥 required [(ngModel)]=鈥渘ewArticle鈥 />
<button (click)=鈥渁ddArticle()鈥>Add article</button>
<ul>
<li *ngIf="sportings.length ===0 ">No hay articulos</li>
<li *ngFor=鈥渓et article of sportings; index as i鈥>
{{i}} {{article}}
<button (click)=鈥渄eleteArticle(i)鈥>Eliminate</button>
</li>
</ul>

Mi lista de deseos, Angular 13 todo funcionado muy bien.

<h1>*ngFor Lista de deseos</h1>
<input type=鈥渢ext鈥 required [(ngModel)]=鈥渘ewWish鈥/>
<button (click)=鈥渁ddWish()鈥>Add Wish</button>
<ul>
<li *ngIf=鈥渨ishes.length === 0鈥>No hay deseos</li>
<li *ngFor=鈥渓et wish of wishes; index as i鈥>
{{ i }}{{ 鈥 '+wish }}
<button (click)=鈥渄eleteWish(i)鈥>Delete</button>
</li>
</ul>

Html combinado
<h1>Mi example list products</h1>
<input type=鈥渢ext鈥 required [(ngModel)]=鈥渘ewProduct鈥>
<button (click)=鈥渁ddProduct()鈥>Add product</button>
<ul *ngIf=鈥減roducts.length > 0; else emptyData鈥>
<!-- variable para interar name -->
<li *ngFor=鈥渓et product of products; index as i鈥>
{{i}} {{ product }}
<button (click)=鈥渄eleteProduct(i)鈥 >Delete</button>
</li>
</ul>
<ng-template #emptyData>
<p>No hay nombres</p>
</ng-template>

html

<input type="text" required [(ngModel)]="newName" >
<button (click)="addName()">Add Name</button>
<ul>
  <li *ngIf="names.length ===0">No hay nombres</li>
  <li *ngFor="let name of names; index as i" >
    {{ i +1}} {{name}} <button (click)="deleteName(i)">Delete Name</button>
  </li>
</ul>

ts


  names: string[] = ['Luis', 'Carlos', 'Giordano','Caleb'];//no es buena practica usar tipado:any
  emojis:string[] = [ '馃槀' , '馃惁', '馃惓','馃尞', '馃挌'];

  newName = '';

  addName(){
    this.names.push(this.newName);
    this.newName = ''
  }

  deleteName(i:number){
    this.names.splice(i,1);//posici贸n y cuantos elementos deseamos eliminar a partir de esta posici贸n
  }

Lista renderizada

En app.component.html:

<h1>Reto</h1>
<h2>Gifs:</h2>
<img *ngFor="let gif of gifs" src={{gif}}>
<hr/> 

En app.component.ts:

gifs = ['https://i.imgur.com/D9Q7i0P.gif', 'https://i.imgur.com/DEfC0z5.gif'];

names: Array <string> = [鈥楧iego鈥, 鈥楴icolas鈥, 鈥楽anty鈥橾;
names: string[] = [鈥楧iego鈥, 鈥楴icolas鈥, 鈥楽anty鈥橾;

<div *ngFor=鈥渓et link of sections; index as i鈥>
<a href="{{ link }}">{{ link }}</a>
</div>

Nos permite iterar sobre elementos HTML de forma dinamica, nos sirve por ejemplo para iterar arrays en listas HTML


<h1>ngFor</h1>
<input type="text" [(ngModel)] = "newName"/>
<button (click)="addName()">Add Name</button>
<ul>
  <li *ngIf="names.length === 0">No hay nombres</li>
  <li *ngFor="let name of names; index as i">
    {{i}} {{name}}
    <button (click)="deleteName(i)">Delete</button>
  </li>
</ul>

Angular me parece maravilloso, gracias Nicolas por ense帽ar este framework, y eso que se apenas lo b谩sico de JS y tambi茅n quiero aprender react

Hola platzinautas

app.component.ts

  newHeroe = '';
  addHeroe() {
    this.heroes.push(this.newHeroe);
    this.newHeroe = '';
  }
  deleteHeroe(idx: number) {
    this.heroes.splice(idx, 1);
  }```

app.componenet.html
```<h1>*ngFor con Heroes</h1>
<input type="text" [(ngModel)]="newHeroe" >
<button (click)="addHeroe()">Add Heroe + </button>
<ul>
  <li *ngIf="heroes.length === 0">Sin Heroes? Empieza a agregar!!!</li>
  <li *ngFor="let heroe of heroes, index as idx" >
    <button (click)="deleteHeroe(idx)" >x</button>
    {{ idx + 1 }} - {{ heroe }}
  </li>
</ul>
<hr>```


Acotaciones
La directiva *ngIf podemos plantear un else con la siguiente sintaxis:

  <p *ngIf="edad>=18; else menor">Es mayor de edad.</p>
  <ng-template #menor><p>Es un menor de edad.</p></ng-template>
En el caso que la condici贸n del *ngIf se verifique falso le indicamos con un else un nombre que debe luego especificarse en un elemento ng-template. Lo que disponemos dentro del elemento ng-template es lo que se muestra.
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  nombre = 'Rodriguez Pablo';
  edad = 40;
  sueldos = [1700, 1600, 1900];
}

ngFor

Estructura que nos permite iterar un array de elementos. Cadenas, n煤meros u objetos.

<h1>ngFor</h1>
<input type="text" required [(ngModel)]="person.name" />
<button (click)="addName(person.name)">Add name</button>
<ul>
  <li *ngIf="names.length === 0">No hay nombres</li>
  <li *ngFor="let name of names; index as i">
    {{i}} {{name}}
    <button (click)="deleteName(i)">Delete</button>
  </li>
</ul>

Agreg贸 el ejercicio, me esta quedando mas claro y lo hice con el listado de super recuperando un poco el curso del innombrable鈥

/* Ejercicios */
/* app.component.ts */
super: string[] = ['Cereal','Leche','Platano','Manzana','Granola']; 
newProducto='';

addProducto () {
  this.super.push(this.newProducto);
  this.newProducto=''; 
}

deleteProducto(index: number){
  this.super.splice(index,1); 
<<!-- app.component.html -->
<hr/>
<h1>Ejercicios Super</h1>
<input type="text" [(ngModel)] ="newProducto" >
<br>
<button (click)="addProducto()" >Agregar producto</button>

<hr/>
<h3>Lista de super guardada</h3>
<ul> 
    <li 
    *ngIf= "super.length ===0"> No hay productos</li> <!-- validacion si hay nombres -->
    <li 
    *ngFor="let super of super; index as i">
        {{i}} {{super}}
        <input type="number" min="1" max="20" placeholder="Cty">

        <button (click) = "deleteProducto(i)">Eliminar</button>
        
    </li>
</ul>
![Captura.PNG](https://static.platzi.com/media/user_upload/Captura-b083506c-e4c6-4de2-8dd2-ff997988c042.jpg)>