Eu tenho um serviço que retorna um observável que faz uma solicitação http ao meu servidor e obtém os dados. Quero usar esses dados mas sempre acabo conseguindo undefined
. Qual é o problema?
Serviço :
@Injectable()
export class EventService {
constructor(private http: Http) { }
getEventList(): Observable<any>{
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get("http://localhost:9999/events/get", options)
.map((res)=> res.json())
.catch((err)=> err)
}
}
Componente:
@Component({...})
export class EventComponent {
myEvents: any;
constructor( private es: EventService ) { }
ngOnInit(){
this.es.getEventList()
.subscribe((response)=>{
this.myEvents = response;
});
console.log(this.myEvents); //This prints undefined!
}
}
Eu verifiquei Como faço para retornar a resposta de uma chamada assíncrona? postar, mas não consegui encontrar uma solução
Respostas:
Razão:
A razão disso
undefined
é que você está fazendo uma operação assíncrona. Isso significa que levará algum tempo para concluir ogetEventList
método (dependendo principalmente da velocidade da rede).Então, vamos dar uma olhada na chamada http.
Depois de realmente fazer ("disparar") sua solicitação http,
subscribe
você estará aguardando a resposta. Enquanto espera, o javascript executará as linhas abaixo deste código e se encontrar atribuições / operações síncronas, ele as executará imediatamente.Então, depois de se inscrever no
getEventList()
e esperar pela resposta,console.log(this.myEvents);
linha será executada imediatamente. E o valor disso é
undefined
antes que a resposta chegue do servidor (ou de qualquer coisa que você inicializou em primeiro lugar).É semelhante a fazer:
Solução:
Portanto, alterando o código para:
irá imprimir a resposta .. depois de algum tempo.
O que você deveria fazer:
Pode haver muitas coisas a fazer com sua resposta além de apenas registrá-la; você deve fazer todas essas operações dentro do callback (dentro da
subscribe
função), quando os dados chegarem.Outra coisa a mencionar é que se você vier de um
Promise
plano de fundo, othen
retorno de chamada corresponderá asubscribe
observáveis.O que você não deve fazer:
Você não deve tentar alterar uma operação assíncrona para uma operação de sincronização (não que você possa). Um dos motivos pelos quais temos operações assíncronas é não fazer o usuário esperar a conclusão de uma operação enquanto ele pode fazer outras coisas nesse período de tempo. Suponha que uma de suas operações assíncronas leve 3 minutos para ser concluída. Se não tivéssemos as operações assíncronas, a interface congelaria por 3 minutos.
Leitura sugerida:
O crédito original para esta resposta vai para: Como retorno a resposta de uma chamada assíncrona?
Mas com o lançamento do angular2, fomos apresentados ao texto datilografado e aos observáveis, portanto, esta resposta esperançosamente cobre os fundamentos do tratamento de uma solicitação assíncrona com os observáveis.
fonte
Fazer uma chamada http em angular / javascript é uma operação assíncrona. Portanto, quando você fizer uma chamada http, ele atribuirá um novo encadeamento para finalizar esta chamada e iniciar a execução da próxima linha com outro encadeamento. É por isso que você está obtendo valor indefinido. então faça as alterações abaixo para resolver isso
fonte
Você pode usar asyncPipe se usar myEvents apenas no modelo.
Aqui, exemplo com asyncPipe e Angular4 HttpClient exemplo
fonte
Os observáveis são preguiçosos, então você precisa se inscrever para obter o valor. Você o inscreveu corretamente em seu código, mas simultaneamente registrou a saída fora do bloco de 'inscrição'. É por isso que é 'indefinido'.
Portanto, se você registrá-lo dentro do bloco de inscrição, ele registrará a resposta corretamente.
fonte
Aqui o problema é que você está inicializando
this.myEvents
emsubscribe()
um bloco assíncrono enquanto está fazendoconsole.log()
apenas fora dosubscribe()
bloco. Portanto,console.log()
ser chamado antes dethis.myEvents
ser inicializado.Mova seu código console.log () também dentro de subscribe () e pronto.
fonte
O resultado é indefinido porque o processo angular é assíncrono. você pode tentar o seguinte:
fonte
Certifique-se também de mapear sua resposta para uma saída json. Caso contrário, ele retornará texto simples. Você faz assim:
fonte
Indefinido porque o valor aqui é registrado antes de qualquer dado do serviço ser definido a partir da chamada de serviço de assinatura acima. Portanto, você deve esperar até que a chamada ajax termine e definir os dados dos dados de resposta.
Aqui, faça o log do console dentro do método de inscrição que fará o log quando os dados forem configurados na variável myEvents.
fonte
Você pode simplesmente tentar este método-
fonte