【问题标题】:Subscribe is not a function of Observable<Interface>订阅不是 Observable<Interface> 的函数
【发布时间】:2021-09-28 16:51:07
【问题描述】:

我正在尝试订阅 Observable,但每次尝试订阅时都会收到此错误:

this.authenticateService.getCurrentUser(...).subscribe 不是 新 HomeComponent 中的函数

我的 getCurrentUser 方法如下所示:

getCurrentUser(): Observable<ICurrentUser> {
        return new Observable<ICurrentUser>(subscriber => {
            from(this.HttpService.get('/user/current')).subscribe(currentUser => {
                subscriber.next(currentUser);
            });
        });
    }

ICurrentUser 接口从 IUser 扩展而来:

    interface IUser {
        uid: string;
        email: string;
        firstname: string;
        name: string;
        language: string;
        companyUid: string;
        companyName: string;
        password?: string;
        newPassword?: string;
        role: string;
        expirationDate: string;
        alternativeEmail?: string;
        alertSubscription?: boolean;
        license?: ILicense;
        isLocked: boolean;
        props: any;
    }
    
    interface ICurrentUser extends IUser {
        timeBeforeExpiration: number;
        graceLoginsRemaining: number;
        usingGraceLogins: boolean;
        autologon: boolean;
        termsAndAgreementsDate: string; // date
        workspaces: number[];
        markets: number[];
        findInAccessibleOnly: boolean;
    }

运行 GET 请求时我从 API 获得的信息:

{
    "uid": "xxxxx-xxxx-xxx-xxx",
    "email": "xxxx@xxxx",
    "firstname": "xxx",
    "name": "xxxx",
    "language": "xx",
    "companyUid": "xxxxx-xxxx-xxxxx-xxxxx",
    "companyName": "xxxx",
    "password": null,
    "newPassword": null,
    "role": "COMPANY_MANAGER",
    "expirationDate": null,
    "alternativeEmail": null,
    "alertSubscription": false,
    "license": null,
    "isLocked": null,
    "props": {
        "ff_findInAccessibleOnly": "true",
        "ff_timer_module": "false",
        "lexprhId": "28936",
        "defaultSearchFilters": "{\"keys\":\"*\",\"suggestReference\":null,\"documentTypeIds\":[],\"attributes\":{\"endDateOfApplicability\":[false],\"findInAccessibleOnly\":[false],\"book\":[],\"type\":[\"101\"],\"nature\":[\"163\",\"105\",\"101\",\"100\",\"103\",\"104\",\"106\",\"107\",\"108\",\"159\",\"158\",\"160\",\"109\",\"157\",\"110\",\"149\",\"115\",\"165\",\"114\",\"116\",\"111\",\"112\",\"113\",\"154\",\"155\",\"156\",\"153\",\"164\",\"117\",\"118\",\"119\",\"121\",\"120\",\"122\",\"124\",\"126\",\"129\",\"125\",\"128\",\"127\",\"130\",\"123\",\"135\",\"145\",\"131\",\"150\",\"134\",\"132\",\"136\",\"133\",\"152\",\"138\",\"151\",\"139\",\"140\",\"141\",\"142\",\"143\",\"144\",\"137\",\"146\",\"147\",\"148\"],\"jurisdiction\":[],\"sourceType\":[],\"source\":[],\"guidelineSource\":[],\"workspace\":[],\"domain\":[],\"territory\":[]},\"pagination\":{\"number\":1,\"size\":30,\"sort\":\"RELEVANCE\"},\"quickSearch\":false}"
    },
    "timeBeforeExpiration": -1,
    "graceLoginsRemaining": -1,
    "usingGraceLogins": false,
    "termsAndAgreementsDate": "2021-06-08T14:48:10.000+00:00",
    "workspaces": [
        1,
        2,
        8,
        101,
        100,
        4,
        102,
        7,
        5,
        3
    ],
    "markets": [
        1,
        0
    ],
    "findInAccessibleOnly": false,
    "autologon": false
}

【问题讨论】:

  • getCurrentUser(): Observable&lt;ICurrentUser&gt; { return new Observable&lt;ICurrentUser&gt;(subscriber =&gt; { from(this.HttpService.get('/user/current')).subscribe(currentUser =&gt; { subscriber.next(currentUser); }); }); } 为什么?
  • 应该是:getCurrentUser = () =&gt; this.HttpService.get('/user/current') 这应该是一个 observable 了。
  • 因为 httpClient 是旧的 ngjs,它提供了 promises 而不是 observables。
  • ΟΚ,首先您应该考虑更改 httpClient 但同样您可以使用from 将promise 转换为可观察的,所以即使在那里:() =&gt; from(this.HttpService.get('/user/current')) 应该可以完成这项工作
  • 你是如何导入Observable的?我猜你是从错误的位置导入的。

标签: angular typescript rxjs observable subscription


【解决方案1】:

如果你的HttpService 正在返回一个承诺,而from() 将一个承诺转换为一个可观察的,为什么不直接返回呢?另外,如果getCurrentUser() 不需要参数,为什么这是一种方法?我建议如下:

getCurrentUser$ = from(this.HttpService.get<ICurrentUser>('/user/current'));

这使得getCurrentUser$ 的类型为Observable&lt;ICurrentUser&gt;。任何订阅它的东西都会收到来自HttpService 承诺的值。

注意:我假设.get() 方法允许泛型,否则您可以使用类型断言。

【讨论】:

    【解决方案2】:

    如果你想得到一个用户的observable,你可以直接从http服务返回:

    getCurrentUser(): Observable<ICurrentUser> {
        return this.HttpService.get('/user/current');
    }
    

    如果你想将它存储在一个变量中,你可以在ngOnInit 中订阅它,比如:

    CurrentUser:ICurrentUser;
    ngOnInit(){
      this.HttpService.get('/user/current').subscribe(user=>{
        this.CurrentUser = user;
      });
    }
    

    如果您使用旧的 http,请使用 from 方法,如下所示:

    getCurrentUser(): Observable<ICurrentUser> {
        return from(this.HttpService.get('/user/current'));
    }
    

    或用于存储在变量中:

    CurrentUser:ICurrentUser;
    ngOnInit(){
      from(this.HttpService.get('/user/current')).subscribe(user=>{
        this.CurrentUser = user;
      });
    }
    

    【讨论】:

    • 是的,问题是我正在使用混合应用程序 ngjs 和 ng10,而我们使用的 httpClient 是来自 ngjs 的旧的返回承诺的客户端。
    • 好的。使用旧 http 的代码编辑答案
    • 这部分没有回答问题,它是不相关(尽管有效)的建议。
    • @Ingo Bürk,OP 并没有真正提出任何问题。据我了解,他希望通过将承诺转换为观察者来成功订阅观察者。我的第三个例子就是答案。如果您对 OP 的要求有其他解释,请分享。
    • 他在问为什么会发生错误。虽然 new Observable 对于用例来说似乎有些矫枉过正,但理论上它应该可以工作。
    【解决方案3】:
    getCurrentUser(): Observable<ICurrentUser> {
        return new Observable<ICurrentUser>(subscriber => {
            from(this.HttpService.get('/user/current')).subscribe(currentUser => {
                subscriber.next(currentUser);
            });
        });
    }
    

    改成

    getCurrentUser(): Observable<ICurrentUser> {
       return this.HttpService.get<ICurrentUser>('/user/current'));
    }
    

    【讨论】:

    • 是的,问题是我正在使用混合应用程序 ngjs 和 ng10,而我们使用的 httpClient 是来自 ngjs 的旧的返回承诺的客户端。
    • 即使这种改变是可能的,它也不会回答问题,而应该是评论。
    猜你喜欢
    • 1970-01-01
    • 2019-09-12
    • 2019-12-29
    • 2016-12-12
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 2023-04-02
    相关资源
    最近更新 更多