¿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: Vista de álbums

31/39
Recursos

Aportes 10

Preguntas 1

Ordenar por:

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

Hola, lo resolví agregando los siguiente a cada archivo fuente:

  1. home.page.ts

async showSongsByAlbum(album) {
const songs = await this.musicService.getAlbumTracks(album.id);
const modal = await this.modalController.create({
component: SongsModalPage,
componentProps: {
songs: songs.items,
artist_or_album: album.name
}
});
modal.onDidDismiss().then(dataReturned => {
this.song = dataReturned.data;
});
modal.present();
}

  1. home.page.html
    <ion-avatar class=“square-avatar” (click)=“showSongsByAlbum(album)”>

  2. platzi-music.service.ts
    getAlbumTracks(albumId) {
    return fetch(
    https://platzi-music-api.now.sh/albums/${albumId}/tracks?country=CO).then(
    response => response.json());
    }

Saludos!

habrá algún servicio para consultar la preview_url de cuando le camos click a una canción en el último slide?

Dado que el código para mostrar la ventana modal con las canciones del artista y las canciones del álbum era muy similar, opté por reutilizar el código de la ventana modal y crear una función donde se realizara su creación y se obtuviera la canción seleccionada.

Además, creo que el uso de una página extra solo para el modal era innecesario, por lo cual opté por crear un componente para la ventana modal, eso sí, había que agregar dicho componente al array declarations y también al array de entryComponents del home.module.ts.

home.page.ts

async showArtistSongs(artist: any) {
    await this.songService.getArtistTopTracks(artist.id).subscribe(async resp => {
      const songs = resp;
      this.showModal(artist, 'Top Tracks', songs.tracks);
    });
  }

  async showAlbumSongs(album: any) {
    await this.songService.getAlbumTracks(album.id).subscribe(async resp => {
      const songs = resp;
      console.log(resp.items);
      this.showModal(album, 'Album Tracks', songs.items);
    });
  }

  async showModal(object: any[], title: string, songs: any) {
    const modal = await this.modalController.create({
      component: SongsModalComponent,
      componentProps: {
        title,
        object,
        songs
      }
    });
    modal.onDidDismiss().then(dataReturned => {
      this.song = dataReturned.data
    })
    return await modal.present();
  }

songs-modal.component.ts

export class SongsModalComponent {
  @Input() artist: any;
  @Input() songs: any[];
  @Input() title: string;

  constructor(private modalController: ModalController) { }

  async selectSong(song: any) {
    await this.modalController.dismiss(song);
  }

  closeModal() {
    this.modalController.dismiss();
  }
  
}

songs-modal.component.html

<ion-header>
  <ion-toolbar>
    <ion-title>{{ object.name }} - {{ title }}</ion-title>
    <ion-buttons slot="end">
      <ion-button (click)="closeModal()">
        <ion-icon name="close"></ion-icon>
      </ion-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item *ngFor="let song of songs; index as i" (click)="selectSong(song)">
      <ion-avatar>
        {{ i +1 }}
      </ion-avatar>
      <ion-label>
        <h2>{{ song.name }}</h2>
        <p>{{ song.popularity }}</p>
      </ion-label>
    </ion-item>
  </ion-list>
</ion-content>

crearemos una función que recupere los tracks de los albums desde la API por lo que cambiaremos primero nuestro musicService

platzi-music.service.ts

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

  

 constructor(

 private http: HttpClient

 ) { }


getAlbumTracks(albumId) {

 return this.http.get(`${this.urlapi}/albums/${albumId}/tracks?country=EC`);

 }

ahora incrementaremos la siguiente función en nuestro home.page.ts

home.page.ts

showAlbums(album) {
	 this.musicService.getAlbumTracks(album.id)
	 .subscribe(songs => {
	 this.modalAlbum(songs, album);
	 }, error => {
		 console.error(error);
	 });
 }

async modalAlbum(songs, album) {
	 const modal = await this.modalController.create({
		 component: SongsModalPage,
		 componentProps: {
			 songs: songs.items,
			 artist: album.name
		 }
	 });
 
 modal.onDidDismiss().then(dataReturned => {
	 this.song = dataReturned.data;
	 });
	 return modal.present();
 }

finalmente actualizamos un html de nuestro home page en la seccion de albums

home.page.html

<h1>Albums</h1>
 <ion-slides [options]='slideOps' *ngIf="albums.length">
	 <ion-slide *ngFor="let album of albums">
		 <ion-avatar (click)="showAlbums(album)" class="square-avatar">
			 <img [src]="album.images[0].url" alt="">
			 <span>{{album.name}}</span>
		 </ion-avatar>
	 </ion-slide>
 </ion-slides>

Por si alguien tuvo problemas con la URL, usen esta:

https://platzi-music-api.herokuapp.com/albums/${albumId}/tracks?country=CO

Función para Mostrar Modal con Canciones

 async modalSong(songArtist, artist) {
    const modal =  await this.modalController.create({
      component: SongsModalPage,
      componentProps: {
        songs: songArtist.tracks ? songArtist.tracks : songArtist.items ,

        artist: artist.name
      }
    });

    modal.onDidDismiss().then(dataReturn => {

      this.song = dataReturn.data;
    });

   return await  modal.present();

  }```

Les comparto mi solución al reto:

home.page.html al dar clic en el avatar se ejecuta la función showAlbumSongs(album) enviando el álbum

<h1>Albums</h1>
    <ion-slides [options]="slideOps" *ngIf="albums.length">
        <ion-slide *ngFor="let album of albums">
            <ion-avatar (click)="showAlbumSongs(album)" class="square-avatar">
                <img [src]="album.images[0].url" />
                <span>{{album.name}}</span>
            </ion-avatar>
        </ion-slide>
    </ion-slides>

home.page.ts Aquí extraje la el llamado del modal en una función llamada showModal() pasándole como parámetros las canciones y el título del modal. Cabe señalar que en los artistas hay “songs.tracks” y que en el álbum hay “songs.items”

    async showArtistSongs(artist) {
        // Llamado al servicion que obtiene los top tracks del artista
        const songs = await this.musicService.getArtistTopTracks(artist.id);
        this.showModal(songs.tracks, artist.name + ' - Top Tracks ');
    }

    async showAlbumSongs(album) {
        // Llamado al servicion que obtiene los top tracks del artista
        const songs = await this.musicService.getAlbumTracks(album.id);
        this.showModal(songs.items, album.name + ' - Album Songs ');
    }

    async showModal(songs, title) {
        // Creación del modal a mostrar al dar clic al artista
        const modal = await this.modalController.create({
            component: SongsModalPage,
            componentProps: {
                songs,
                title
            }
        });
        // onDidDismiss se ejecuta automáticamente al ocultarse el modal
        modal.onDidDismiss().then(dataReturned => {
            this.song = dataReturned.data;
        });
        return await modal.present();
    }

songs-modal.page.ts Aquí solo cambie la propiedad artist por title para mostrar un titulo adecuado para artistas y álbumes.

    songs: any[];
    title: string; // Titulo del modal
    constructor(private navParams: NavParams, private modalController: ModalController) { }

    ionViewDidEnter() {
        // NavParams se trae los datos del modal
        this.songs = this.navParams.data.songs;
        this.title = this.navParams.data.title;
    }

songs-modal.page.html Aquí solo modifique el ion-title pasándole la propiedad title. Y dado que los ítems del álbum no tienen la propiedad “popularity” decidí mostrar la duración de la canción parseada creando la función parseTime en songs-modal.page.ts.

<ion-title>{{ title }}</ion-title>
...
<p>{{ song.popularity || parseTime(song.duration_ms) }}</p>

home.page.html agregue el llamado a la funcion showAlbums(album) enviando el parametro de album

<ion-avatar (click)="showAlbums(album)" class="square-avatar">
        <img [src]="album.images[0].url" alt="via placeholder">
        <span>{{ album.name }}</span>
      </ion-avatar>

home.page.ts se creo la funcion showAlbums para mandar llamar el servicio de getAlbumsTracks y mostrarlo en el modal SongModalPage

async showAlbums(album){
    const albums = await this.musicService.getAlbumTracks(album.id);
    const modal = await this.modalController.create({
      component: SongsModalPage,
      componentProps :{
        songs: albums.items,
        title: album.name
      }
    });
    modal.onDidDismiss().then(dataRetuned=>{
      this.song = dataRetuned.data;
    })
    modal.present();
  }
 async showSongs(data, type) {
    this.presentLoading();
    let songs: any;
    switch (type) {
      case 1:
        songs = await this.musicService.getArtistTopTracks(data.id);
        songs = songs.tracks;
        break;
      case 2:
        songs = await this.musicService.getAlbumTracks(data.id);
        songs = songs.items;
        break;
      default:
        break;
    }
    console.log(songs);
    const modal = await this.modalCtrl.create({
      component: SongsModalPage,
      componentProps: {
        songs,
        name: data.name
      }
    });
    this.loading.dismiss();
    console.log('modal', modal);
    modal.onDidDismiss().then((dataReturn: any) => {
      if (dataReturn.data) {
        // this.currentSong = null;
        this.currentSong = {};
        this.song = dataReturn.data;
        this.play();
      }
    });
    return await modal.present();

  }

En home.page.html
<ion-avatar class=“square-avatar” (click)=“showSongsbyAlbum(album)”>
<img [src]=“album.images[0].url” />
<span>{{album.name}}</span>

en home.page.ts
async showSongsbyAlbum(album){
console.log(album);
const songs = await this.musicService.getAlbumTracks(album.id);
console.log(songs);
const modal = await this.modalController.create({
component: SongsModalPage,
componentProps: {
songs: songs.items,
album: album.name,
},
});
modal.onDidDismiss().then((dataReturned) => {
this.song = dataReturned.data;
});
return await modal.present();
}

En platzi-music.service.ts
getAlbumTracks(albumId){
return fetch(
https://platzi-music-api.now.sh/albums/${albumId}/tracks?country=CO
).then(response => response.json());
}