Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Como mudar o valor do número de comentários automaticamente?

Olá,

Estou tentando implementar no sistema da alurapic algo similar ao que foi acrescentado no método "like", para atualizar o valor do número de comentários toda a vez que o comentário for adicionado. Mas, estou um pouco perdido. Pensei em utilizar o @Output e EventEmitter, e, talvez o BehaviorSubject. Mas, estou na dúvida como implementá-los..

Componente pai: Photo-details html

<div class="bg-white border" *ngIf="(photo$ | async) as photo">
    <div class="row ml-1 mr-1">
      <div class="col-lg-7 text-center">
        <ap-photo [url]="photo.url" [description]="photo.description"></ap-photo>
      </div>

      <div class="col-lg-4 ml-1 mr-1 p-4">
        <p class="text-lg-left break-word">{{ photo.description }}</p>
        <small>
          <div class="text-left mb-4">
            <i
              (click)="like(photo)" 
              class="fa fa-heart-o fa-2x mr-2 pull-left"
            >
            </i>{{ photo.likes }}
            <i
              class="fa fa-comment-o fa-2x mr-2 ml-2"
            >
            </i>{{ photo.comments }}
            <i 
              photoOwnerOnly [ownedPhoto]="photo" 
              (click)="remove()" 
              class="fa fa-trash-o fa-2x pull-right"
            >
            </i>
        </div>
          <hr>
        </small>
        <ap-photo-comments
          *ngIf="photo.allowComments; else warning"
          [photoId]="photoId"
        >
        </ap-photo-comments>
        <ng-template #warning>
          <p>User has disabled comments for this photo</p>
        </ng-template>
      </div>
    </div>
  </div>

ts

export class PhotoDetailsComponent implements OnInit { 

    photo$: Observable<Photo>;
    photoId: number;
    public commentsCount: number; 

    constructor(
        private route: ActivatedRoute,
        private photoService: PhotoService,
        private router: Router,
        private alertService: AlertService,
        private userService: UserService
    ) { }

    ngOnInit(): void {
        this.photoId = this.route.snapshot.params.photoId;
        this.photo$ = this.photoService.findById(this.photoId);
        this.photo$
            .subscribe(
                () => {},
                err => { 
                    this.router.navigate(['not-found']);
                    console.log(err); 
                }
            );
    }

// código remove() 

    like(photo: Photo) { 
        this.photoService
            .like(photo.id)
            .subscribe(
                liked => {
                    if(liked){
                        this.photo$ = this.photoService.findById(photo.id);
                    }
                },
                err => {
                    console.log(err);
                    this.alertService.warning('Please, login first.', true);
                    this.router.navigate(['']);
                }
            );
    }
}

Componente filho: Photo-comments html

<div class="mt-4">
        <form [formGroup]="commentForm" (submit)="save()">
          <div class="input-group">
            <textarea 
                formControlName="comment" 
                class="form-control"
            >
            </textarea>
            <div class="input-group-append">
                <button 
                    class="btn btn-dark pull-left"
                    [disabled]="commentForm.invalid || commentForm.pending" 
                >Publish
                </button>
            </div>
          </div>
        <ap-vmessage
          text="Maximun size allowed is 300"
          *ngIf="commentForm.get('comment').errors?.maxlength"
        >
        </ap-vmessage>
        </form>
    </div>

ts

save() {
        if(this.userService.isLogged()) {
            const comment = this.commentForm.get('comment').value as string;
            this.comments$ = this.photoService
                .addComment(this.photoId, comment)
                .pipe(switchMap(() => this.photoService.getComments(this.photoId)))
                .pipe(tap(() => {
                    this.commentForm.reset();
                    this.alertService.success('Comment has been added!');
                }));
        } else {
            this.alertService.warning('Login before comment', true);
            this.router.navigate(['']);
        }
    };
5 respostas

Fala ai William, tudo bem? Isso pode ser resolvido de N maneiras, do jeito que você fez, parece estar correto, você chama a API de like e caso tudo dê certo você atualiza a propriedade $photo.

Não está funcionando?

Nesse caso não precisa de @Output ou EventEmitter porque a regra toda está no próprio componente PhotoDetailsComponent.

Uma vez que a foto recebeu o like, a API processou, e você buscou a nova foto, o like deveria ter ter o novo valor com a quantidade nova.

Espero ter ajudado.

Olá, Matheus! Obrigado pelo retorno. Na verdade o like está funcionando, eu gostaria de fazer a mesma funcionalidade para o número de comentários

solução!

Entendi, nesse caso você pode fazer de N maneiras, eu sugiro:

No PhotoComments você receber uma propriedade Output.

@Output() hasNewComment = new EventEmitter();

E dentro da função de adicionar um comentário, no trecho onde a API retornar o sucesso que tudo deu certo, pode emitir um evento para o pai com o EventEmitter.

.pipe(tap(() => {
    // nesse trecho
    this.hasNewComment.emit();
    this.commentForm.reset();
    this.alertService.success('Comment has been added!');
}));

Ai no seu componente pai, você cria uma função que vai receber esse evento do filho:

updateCommentsCount() {
    this.commentsCount ++;
}

E no template passa ela para o Output do filho:

<ap-photo-comments
    *ngIf="photo.allowComments; else warning"
    [photoId]="photoId"
    (hasNewComment)="updateCommentsCount()"
>

Por fim, no lugar onde você mostra a quantidade de comentário, você pode tentar somar com o commentsCount:

<i class="fa fa-comment-o fa-2x mr-2 ml-2"></i>{{ photo.comments + commentsCount }}

Acho que isso deve dar certo.

Espero ter ajudado.

Olá, Matheus!

Funcionou!!! Muito obrigado :D A única alteração que tive que fazer no código foi inicializar o valor de zero no commentsCount!

Muito obrigado mesmo!

Show William, magina, sempre que precisar não deixe de criar suas dúvidas.

Abraços e bons estudos.