¿Qué es Ionic?

1

Requisitos del curso y presentación del proyecto

2

¿Qué hay de nuevo en Ionic 4?

3

¿Qué ha cambiado en Ionic?

4

Instalación de Ionic y templates básicos

5

Instalación de Capacitor y uso en Android Studio

6

Uso de Capacitor y xCode

7

Sincronizando nuestro proyecto con los emuladores

Componentes básicos de Ionic

8

El componente Slides

9

CSS y Custom Properties de los componentes de Ionic

10

Slides dinámicos

11

Angular Router e Ionic Storage

12

Controlar la navegación con Guards

13

Utilidades de CSS con Ionic

14

Crear una página de login

15

Validar inputs del formulario de login

16

Envío del formulario

17

Servicio para validar credenciales

18

Agregar Guards a nuestro login

19

Crear una página de registro

20

Navegación entre login y registro

21

Agregar un menú con el componente Menu

22

Dar funcionalidad y estilos al menú

23

Uso de componente Slides y opciones avanzadas

Consumo y manejo de informacion con Ionic

24

Consumiendo un API para llenar información de nuestros artistas

25

Página completa con artistas, canciones y álbums

26

El componente Modal y el Modal Controller

27

Llenar de contenido el Modal

28

Componente Footer y funcionalidad del Modal

29

Construyendo nuestro reproductor

30

Lógica de nuestro reproductor

31

RETO: Vista de álbums

Acceso al hardware

32

Usar la cámara a través de Capacitor

33

Corrección de errores y afinando detalles

34

Mejorando nuestra página de Settings con CSS

35

Página Sports y Angular Maps

36

Crear la página Sport

37

RETO: Buscador dinámico en Sports

38

Llevar nuestra aplicación a producción con Android

39

Llevar nuestra aplicación a producción con iOS y cierre del curso

Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de Ionic 4

Curso de Ionic 4

Sebastián Gómez

Sebastián Gómez

RETO: Buscador dinámico en Sports

37/39
Recursos

Aportes 8

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Esta es mi solución al reto.

sportspage.ts

@Component({
  selector: 'app-sports',
  templateUrl: './sports.page.html',
  styleUrls: ['./sports.page.scss'],
})
export class SportsPage {
  currentCenter: Coordinate;
  coordinates: Coordinate[] = [];
  defaultZoom = 14;
  searching = false;
  text = 'Enter keywords to perform a search.';
  songs: any[];
  song: any;
  currentSong: HTMLAudioElement;

  constructor(
    private songService: SongService
  ) { }

  ionViewDidEnter() {
    this.getCurrentPosition();
    this.watchPosition();
  }

  async getCurrentPosition() {
    const coordinates = await Geolocation.getCurrentPosition();
    this.currentCenter = {
      latitude: coordinates.coords.latitude,
      longitude: coordinates.coords.longitude
    };
  }

  async watchPosition() {
    Geolocation.watchPosition({}, pos => {
      this.currentCenter = {
        latitude: pos.coords.latitude,
        longitude: pos.coords.longitude
      };
      this.coordinates.push(this.currentCenter);
    });
  }

  async getTracks(keywords: string) {
    this.searching = true;
    if (keywords.length > 0) {
      this.songService.searchTracks(keywords).subscribe(async resp => {
        this.songs = await resp.tracks.items.filter((item: any) => item.preview_url);
        if (this.songs.length === 0) {
          this.text = 'There are no results for these keywords.';
        }
        this.searching = false;
      });
    } else {
      this.text = 'Enter keywords to perform a search.';
      this.songs = [];
    }
  }

  play(song: any) {
    if (this.currentSong) {
      this.pause();
    }
    this.song = song;
    this.currentSong = new Audio(this.song.preview_url);
    this.currentSong.play();
    this.currentSong.addEventListener('ended', () => this.song.playing = false);
    this.song.playing = true;
  }

  pause() {
    this.currentSong.pause();
    this.song.playing = false;
  }
}

sportpage.html

<ion-header>
  <ion-toolbar>
    <ion-title>Sports</ion-title>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <agm-map 
    *ngIf="currentCenter"
    [zoom]="defaultZoom"
    [latitude]="currentCenter.latitude"
    [longitude]="currentCenter.longitude">
    <agm-marker
      [latitude]="currentCenter.latitude"
      [longitude]="currentCenter.longitude"
      iconUrl="assets/img/bicycle.png">
    </agm-marker>
    <agm-polyline [strokeColor]="'red'" *ngIf="coordinates">
      <agm-polyline-point 
        *ngFor="let coordinate of coordinates"
        [latitude]="coordinate.latitude"
        [longitude]="coordinate.longitude"></agm-polyline-point>
    </agm-polyline>
  </agm-map>
  <div class="ion-padding">
    <ion-searchbar (keyup)="getTracks($event.target.value)"></ion-searchbar>

    <h2>Tracks</h2>

    <div class="ion-text-center" *ngIf="searching">
      <ion-spinner name="crescent"></ion-spinner>
    </div>
    
    <div *ngIf="!songs || songs.length === 0">
      <h3>Opps! There are no songs.</h3>
      <ion-text>
        {{ text }}
      </ion-text>
    </div>

    <ion-virtual-scroll 
      [items]="songs"
      *ngIf="songs">
      <ion-item *virtualItem="let song">
        {{ song.name }}
        <ion-buttons slot="end">
          <ion-button (click)="pause()" *ngIf="song.playing">
            <ion-icon name="pause"></ion-icon>
          </ion-button>
          <ion-button *ngIf="song.playing">
            <ion-spinner name="dots"></ion-spinner>
          </ion-button>
          <ion-button (click)="play(song)" *ngIf="!song.playing">
            <ion-icon name="play"></ion-icon>
          </ion-button>
        </ion-buttons>
      </ion-item>
    </ion-virtual-scroll>
  </div>
</ion-content>

Creo que el video no corre.

El curso de IONIC ha estado genial, me gustaría que lo actualizaran a la versión 6, tal vez una serie de cursos seria mejor, cada uno profundizando un tema.

primero crearemos un nuevo metodo en el servicio de platzimusic

platzi-music.service.ts

private urlapi = 'https://platzi-music-api.herokuapp.com';

searchTracks(keywords) {
    return this.http.get(`${this.urlapi}/search?q=${keywords}&type=track`);
  }

crearemos un archivo llamado songs.model.ts, dentro de una carpeta llamada models para poder exportar la interfaz de song

song.model.ts

export interface Song {
  name?: string;
  playing: boolean;
  // eslint-disable-next-line @typescript-eslint/naming-convention
  preview_url?: string;
  tracks?: string[];
};

ahora se podrán hacer los cambios en sports page

sports.page.ts

import { Song } from '../../models/song.model';
import { PlatziMusicService } from '../services/platzi-music.service';

export class SportsPage {

  currentCenter: any;
  coordinates: google.maps.LatLngLiteral[] = [];
  defaultZoom = 14;
  center: google.maps.LatLngLiteral;
  searching = false;
  text = 'Ingrese la canción a buscar';
  songs: Song[];
  song: Song;
  currentSong: HTMLAudioElement;

  constructor(
    private songService: PlatziMusicService
  ) { }

  ionViewDidEnter() {
    this.getCurrentPosition();
    this.watchPosition();
  }

  async getCurrentPosition() {
    const coordinates = await Geolocation.getCurrentPosition();
    this.currentCenter = {
      lat: coordinates.coords.latitude,
      lng: coordinates.coords.longitude
    };
    this.center = {
      lat: coordinates.coords.latitude,
      lng: coordinates.coords.longitude
    };
  }

  watchPosition() {
    Geolocation.watchPosition({}, position=> {
      this.center = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      };
      this.coordinates.push ({
        lat: position.coords.latitude,
        lng: position.coords.longitude
      });
    });
  }

  async getTracks(keywords) {
    this.searching = true;
    if(keywords.length > 0) {
      this.songService.searchTracks(keywords)
      .subscribe(async resp => {
        // eslint-disable-next-line @typescript-eslint/dot-notation
        this.songs = await resp['tracks'].items
        .filter((item: any) => item.preview_url);
        if (this.songs.length === 0) {
          this.text = 'No hay resultados de la busqueda.';
        }
        this.searching = false;
      });
    } else {
      this.text = 'Ingrese una canción a la busqueda';
      this.songs = [];
    }
  }

  play(song: Song) {
    if ( this.currentSong) {
      this.pause();
    }
    this.song = song;
    this.currentSong = new Audio(this.song.preview_url);
    this.currentSong.play();
    this.currentSong.addEventListener('ended', () =>
    this.song.playing = false);
    this.song.playing = true;
  }

  pause() {
    this.currentSong.pause();
    this.song.playing = false;
  }
}

Aquí esta la vista de la solución al reto, lo que hice fue volver el reproductor un componente así podía usarlo tanto en el home como en la pantalla de sports

No funciona

sports.page.html

<ion-searchbar (ionInput)="searchSongs($event.target.value)" placeholder="Search Song"></ion-searchbar>
 <div class="ion-text-center" *ngIf="searching">
  <ion-spinner name="circles"></ion-spinner> 
 </div>

 <ion-virtual-scroll [items]="songs" *ngIf="songs">
  <ion-item *virtualItem="let song; index as i">
    <ion-avatar>
      {{ i+1 }}
    </ion-avatar>
    <ion-label>
      <h2>{{ song.name }}</h2>
    </ion-label>
    <ion-icon name="play" (click)="play(song,i)" *ngIf="!song.playing"> </ion-icon>
    <ion-icon name="pause" (click)="pause(i)" *ngIf="song.playing"> </ion-icon>
    <ion-spinner name="dots"  *ngIf="song.playing"></ion-spinner>
  </ion-item>
</ion-virtual-scroll>

sports.page.ts

async searchSongs(text: any){
    this.searching= true;
    const songs = text.length > 0 ? await this.musicService.searchTracks(text): "";
    if(!(songs === "")){
      this.songs = songs.tracks.items;
      this.searching= false;
    }else{
      this.songs=[];
      this.searching= false;
    }   
  }
  play(song, i){
   if(this.currentSong && this.valueChangedSong>=0 ){
      this.songs[this.valueChangedSong]['playing'] = false;
      this.currentSong.pause();
   }
    this.currentSong = new Audio(song.preview_url);
    this.currentSong.play();
    this.songs[i]['playing'] = true;
    this.valueChangedSong=i;
  }
  pause(i){
    this.currentSong.pause();
    this.songs[i]['playing'] =false;
    }

En ocaciones ingresas a la sección “Sports”, el mapa no carga y en la consola aparece este error: E_RROR TypeError: Cannot read property ‘coords’ of null_
¿A que se debe?