4
respostas

Como fazer uma chamada no angular com dois observables? Sendo que o segundo precisa esperar o primeiro acabar

Como fazer uma chamada no angular com dois observables? Sendo que o segundo precisa esperar o primeiro acabar.

Tenho o observable1 e observable2, o observable2 só pode iniciar quando o observable1 terminar, pois eu preciso de uma informação do observable1 para ser usada na requisição observable2.

Meu caso de uso acho que é um pouco diferente. Preciso mostrar um lista de atividades na tela, nestas atividades eu tenho apenas o id de quem a realizou. Mas preciso mostrar as atividades na tela com o nome de quem a fez e pra isso preciso fazer a busca dos usuários após o termino da primeira requisição. Quando as duas requisições terminarem eu preciso fazer um map e substituir o id do usuario pelo nome

4 respostas

Olá Tales, tudo bem?

Entre os operadores do RxJS, existem quatro que são comumente usados para lidar com observables que emitem valores no momento em que outro observable é emitido: switchMap, concatMap, mergeMap e exhaustMap.

Esses operadores são semelhantes, mas têm diferenças importantes em relação a como eles lidam com os observables emitidos.

switchMap:

Esse operador é usado quando você tem um observable de entrada e quer transformá-lo em outro observable de saída. Ele cancela as requisições anteriores e apenas devolve o valor do último pedido. Ele é útil para situações em que você deseja cancelar uma solicitação de servidor pendente sempre que uma nova solicitação for feita.

mergeMap:

O operador mergeMap é semelhante ao switchMap, mas ele não cancela a emissão anterior quando um novo valor é emitido. Em vez disso, ele emite todos os valores emitidos pelo observable de entrada, mesmo que a emissão anterior ainda não tenha sido concluída. Ele é útil em situações em que você deseja combinar vários fluxos de dados em um único fluxo.

concatMap:

Também semelhante ao switchMap, porém o concatMap espera que o observable de saída seja concluído antes de começar a emitir novos valores do observable de entrada. É útil em situações em que a ordem é importante e você deseja processar os valores emitidos pelo observable de entrada em uma sequência específica.

exhaustMap:

Esse operador ignora os valores emitidos pelo observable de entrada enquanto o observable de saída ainda estiver emitindo valores. É útil em situações em que você deseja ignorar as solicitações adicionais enquanto a primeira solicitação ainda estiver em andamento e até que seja concluída. É comum em casos de login, por exemplo.

Cada um desses operadores tem um uso específico dependendo da situação seja para transformar ou combinar fluxos de dados assíncronos de maneiras diferentes.

Espero ter ajudado! Bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado. ✓

Tem o map do RxJS também. Você pode mapear esse retorno do primeiro observable, e na sequência de acordo com o resultado charmar o segundo. Tem que verificar se você quer o resultado do primeiro junto com o segundo ou apenas o segundo. Além das opções da Nayanne, essa é mais uma.

Meu caso de uso acho que é um pouco diferente. Preciso mostrar um lista de atividades na tela, nestas atividades eu tenho apenas o id de quem a realizou. Mas preciso mostrar as atividades na tela com o nome de quem a fez e pra isso preciso fazer a busca dos usuários após o termino da primeira requisição. Quando as duas requisições terminarem eu preciso fazer um map e substituir o id do usuario pelo nome.

Então... é justamente isso que falei. Vou exemplificar pra ver se fica melhor:

this.blogService
      .get(blogId)
      .pipe(
        map((blog) => {
          if (blog.photoId) {
            this.photoService
              .get(blog.photoId)
              .pipe(tap((photo) => (this.blogPhotoUrl = photo.imageUrl)))
              .subscribe();
          }

          return blog;
        })
      )
      .subscribe((blog) => (this.blog = blog));

Dá pra melhorar o código e evitar esse subscribe no final, e usar um async pipe. Mas a ideia é evitar usar subscribe dentro de subscribe. Acho que este exemplo é bem parecido com o que vc precisa. Eu tenho uma chamada para obter o blog e outra pra obter a photo usada nele, porém quando termina a primeira chamada, preciso do id da photo que está no retorno dela, e só ai faço a request da photo. No photoService eu usei um tap, pq achei melhor, para não ter que tratar meu retorno e mudar a tipagem. Mas vc pode criar um novo objeto retornando o que vc precisa e etc.

Espero que isso te ajude.