При использовании функции subscribe получение не удается прочитать неопределенное

#angular #firebase #rxjs

#angular #firebase #rxjs

Вопрос:

Я пытаюсь получить информацию от другого компонента, который отправляет HTTP-запрос с помощью youtube API, и я получаю эту проблему:

 Cannot read property 'subscribe' of undefined
at SafeSubscriber._next (profile.page.ts:20)
  

это код компонента, отсюда я пытаюсь получить информацию из сервиса:

   constructor(private db:FirebaseService,private afauth:AuthService) { 
  this.db.getDataObj("/Profile/"   this.uid).subscribe(res =>{
     this.profileInfo= res;
     this.afauth.getYoutubeData(res.channel).subscribe(data =>{
       console.log(data);
  })
})}
  

это код функции службы, которая отправляет http-запрос:

  getYoutubeData(ch):any{
  let m="https://www.googleapis.com/youtube/v3/channels? 
  part=snippet,contentDetails,statisticsamp;id="   ch   "amp;key="   api ;
  this.http.get(m).subscribe(data =>
  { 
   this.youtubeObj=data.items["0"].statistics;
   return this.youtubeObj;
 })
  

}

Комментарии:

1. Вы не можете возвращать данные из subscribe таким образом, это фактически не вернет данные. Вместо этого вы можете использовать операторы RxJS, такие как map() внутри pipe(), для передачи форматированных наблюдаемых потоковых данных другим методам.

Ответ №1:

Вам необходимо исправить свой getYoutubeData метод в службе, удалив подписку и вернув this.http.get . Чтобы получить data.items["0"].statistics из подписки на getYoutubeData , используйте операторы pipe amp; map :

 import { catchError, map } from 'rxjs/operators';

getYoutubeData(ch): any {
  let m="https://www.googleapis.com/youtube/v3/channels? 
  part=snippet,contentDetails,statisticsamp;id="   ch   "amp;key="   api;
  return this.http.get(m).pipe(
    map(data => data.items["0"].statistics),
    catchError(err => {
      console.log(err);
    });
  )
}
  

Ответ №2:

Проблема здесь в том, что вы в принципе не можете возвращать данные из subscribe . Таким образом, решением здесь было бы просто вернуть Observable и получить данные в конструкторе компонента.

.service.ts

  getYoutubeData(ch):any{
  let m="https://www.googleapis.com/youtube/v3/channels? 
  part=snippet,contentDetails,statisticsamp;id="   ch   "amp;key="   api ;
  return this.http.get(m);
}
  

*.component.ts

 constructor(private db:FirebaseService,private afauth:AuthService) { 
  this.db.getDataObj("/Profile/"   this.uid).subscribe(res =>{
     this.profileInfo= res;
     this.afauth.getYoutubeData(res.channel).subscribe(data =>{
       console.log(data.items["0"].statistics);
  })
})}
  

Ответ №3:

Вы уже подписываетесь в getYoutubeData методе. Вы можете подписаться только один раз. В вашем методе, пожалуйста, используйте метод pipe и tab, например :

 getYoutubeData(ch):any{
  let m="https://www.googleapis.com/youtube/v3/channels? 
  part=snippet,contentDetails,statisticsamp;id="   ch   "amp;key="   api ;
  return this.http.get(m).pipe(tap(data =>
  { 
   this.youtubeObj=data.items["0"].statistics;
   return this.youtubeObj;
 }))
}
  

Комментарии:

1. Вы имеете в виду tap метод?