【问题标题】:Using subscribe function getting cannot read undefined使用订阅函数获取无法读取未定义
【发布时间】:2019-03-10 20:30:55
【问题描述】:

我正在尝试从另一个使用 youtube API 发送 HTTP 请求的组件获取信息,但我遇到了这个问题:

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%2CcontentDetails%2Cstatistics&id=" + ch + "&key=" + api ;
  this.http.get(m).subscribe(data =>
  { 
   this.youtubeObj=data.items["0"].statistics;
   return this.youtubeObj;
 })

}

【问题讨论】:

  • 你不能像这样从订阅中返回数据,它实际上不会返回数据。相反,您可以在 pipe() 中使用诸如 map() 之类的 RxJS 运算符将格式化的可观察流数据传递给其他方法。

标签: angular firebase rxjs


【解决方案1】:

您需要通过删除订阅并返回this.http.get 来更正服务中的getYoutubeData 方法。要从订阅中获取 data.items["0"].statisticsgetYoutubeData,请使用 pipemap 运算符:

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

getYoutubeData(ch): any {
  let m="https://www.googleapis.com/youtube/v3/channels? 
  part=snippet%2CcontentDetails%2Cstatistics&id=" + ch + "&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%2CcontentDetails%2Cstatistics&id=" + ch + "&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 方法。您只能订阅一次。在您的方法中,请使用管道和选项卡方法,例如:

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

      【讨论】:

      • 你的意思是tap方法吗?
      猜你喜欢
      • 1970-01-01
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      相关资源
      最近更新 更多