Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Componente ap-photos sendo carregado antes do final da consulta de dados na api

Essa foi até uma dúvida passada de alguém aqui do fórum mas aparentemente o problema era outro.

No meu caso, após a criação do novo componente ap-photos a aplicação parou de exibis as imagens.

Coloquei alguns logs nos métodos e constatei que o componente ap-photos está carregando antes do array de fotos ser inicializado pela api no PhotoListComponent.

Ou seja, quando chega no método ngOnInit do PhotosComponent o array photos está vazio e assim não inicia o array rows (utilizado no template).

Pra mim até faz sentido pois o array é carregado em um código assíncrono, mas pq funcionou para o instrutor?

Veja os logs

Entrou no ngOnInit do PhotoListComponent 
Saiu do ngOnInit do PhotoListComponent com 0 fotos
Entrou no ngOnInit do PhotoComponent com 0 fotos 
Finalizou o subscribe do PhotoListComponent com 14 fotos

Meu código

  • PhotoListComponent
...
export class PhotoListComponent implements OnInit {

  photos: Photo[] = []

  constructor(
    private photoService: PhotoService,
    private activatedRoute: ActivatedRoute) { }

  ngOnInit(): void {

    console.log(`Entrou no ngOnInit do PhotoListComponent`);

    const userName = this.activatedRoute.snapshot.params.userName;
    this.photoService.listFromUser(userName)
      .subscribe(
        photos => {
          this.photos = photos;
          console.log(`Finalizou o subscribe do PhotoListComponent com ${this.photos.length} fotos`);
        },
        err => console.log(err.message)
      );

      console.log(`Saiu do ngOnInit do PhotoListComponent com ${this.photos.length} fotos`);
  }

}
  • PhotosComponent
...
export class PhotosComponent implements OnInit {

  @Input() photos: Photo[] = []
  rows: any[] = [];

  constructor() { }

  ngOnInit() {    
    console.log(`Entrou no ngOnInit do PhotoComponent com ${this.photos.length} fotos`);
    this.rows = this.groupColumns(this.photos);
  }

  groupColumns(photos : Photo[]) {
    let newRows: any[] = [];
    for(let index = 0; index < photos.length; index ++) {
      newRows.push(photos.slice(index, index + 3));
    }
    return newRows;
  }
}

Acredito que não deveria ter funcionado mesmo mas a pergunta é: Como garantir que PhotosComponent seja carregado apenas após o subscribe do PhotoListComponent?

Eu consegui contornar esse problema criando um getter para rows mas não sei se é a melhor saída.

export class PhotosComponent implements OnInit {

  @Input() photos: Photo[] = []
  private _rows: any[] = [];

  constructor() { }

  ngOnInit() {    
    console.log(`Entrou no ngOnInit do PhotoComponent com ${this.photos.length} fotos`);    
  }

  get rows() {
    console.log(`Chamou o getter com ${this.photos.length} fotos`);    
    this._rows = this.groupColumns(this.photos);
    return this._rows;
  }

  groupColumns(photos : Photo[]) {
    let newRows: any[] = [];
    for(let index = 0; index < photos.length; index ++) {
      newRows.push(photos.slice(index, index + 3));
    }
    return newRows;
  }
}

Daí o log ficou assim

Entrou no ngOnInit do PhotoListComponent 
Saiu do ngOnInit do PhotoListComponent com 0 fotos
Entrou no ngOnInit do PhotoComponent com 0 fotos 
Chamou o getter com 0 fotos
Finalizou o subscribe do PhotoListComponent com 14 fotos 
Chamou o getter com 14 fotos
1 resposta
solução!

O próprio vídeo da aula https://cursos.alura.com.br/course/angular-fundamentos/task/38781 respondeu a minha questão. :-)