我为什么得到:TypeError:this.tenantQueryParamResolve不是一个函数

时间:2016-07-22 00:31:24

标签: typescript angular promise

重现步骤

我有一个Angular 2 TypeScript服务,在Angular 1 / Angular 2混合环境中运行,旨在捕获URL参数(租户)并使用此参数来设置组件属性。

此服务需要弥补$ routeParams或类似服务在此环境中不可用的事实。

该服务有两种方法:

  • setTenantQueryParam - 使用 $ routeParams 服务从Angular 1控制器调用,并用于解析带有参数名称的promise。
  • getTenantQueryParam - 从请求参数值的Angular 2组件调用。它返回一个已解决的promise,调用上面的 setTenantQueryParam

这是代码:

import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Observable";

@Injectable()
export class MigrationHelperService {
    tenantQueryParam: string;
    tenantQueryParamResolve: (x: string) => void;

    setTenantQueryParam(tenant: string) {
        this.tenantQueryParam = tenant;
        this.tenantQueryParamResolve(tenant);
    }

    getTenantQueryParam(): Promise<string> {
        if (this.tenantQueryParam !== undefined) {
            return Promise.resolve(this.tenantQueryParam);
        }
        else {
            let deferred = Q.defer<void>();
            return  new Promise<string>(
                function (resolve) {
                    this.tenantQueryParamPromiseResolve = resolve;
                }
            );
        }
    }
}

观察到的行为

该软件中断执行:

this.tenantQueryParamResolve(tenant);

带有以下消息:

angular.js:13550 TypeError: this.tenantQueryParamResolve is not a function
    at MigrationHelperService.setTenantQueryParam (http://localhost:8080/iq/ng2/util/MigrationHelperService.js:31:26)
    at new eval (http://localhost:8080/iq/js/app.js:5703:36)
    at Object.instantiate (http://localhost:8080/iq/js/appVendor.js:16322:14)
    at $controller (http://localhost:8080/iq/js/appVendor.js:21772:28)
    at link (http://localhost:8080/iq/js/appVendor.js:45012:26)
    at invokeLinkFn (http://localhost:8080/iq/js/appVendor.js:21336:9)
    at nodeLinkFn (http://localhost:8080/iq/js/appVendor.js:20735:11)
    at compositeLinkFn (http://localhost:8080/iq/js/appVendor.js:20039:13)
    at publicLinkFn (http://localhost:8080/iq/js/appVendor.js:19919:30)
    at lazyCompilation (http://localhost:8080/iq/js/appVendor.js:20257:25) <div id="view" ng-view="" class="ng-scope">

预期行为

作业

this.tenantQueryParamPromiseResolve = resolve; 
getTenantQueryParam 方法中的

正常工作,正确设置 tenantQueryParamResolve

我怀疑这是 getTenantQueryParam 中范围的问题;我尝试过多种替代方案都无济于事。是时候有人知道他们在做什么帮助我了!

提前感谢您的帮助。真诚的,罗德里戈。

Postscript Note

我在 this.tenantQueryParamPromiseResolve = resolve; 任务中添加了一个try / catch块:

try {
    this.tenantQueryParamPromiseResolve = resolve;
}
catch(err) {
    console.log(err.stack);
}

作业失败了!以下消息:

Failed to assign
MigrationHelperService.ts:75 TypeError: Cannot set property 'tenantQueryParamPromiseResolve' of undefined
    at eval (MigrationHelperService.ts:71)
    at new ZoneAwarePromise (zone.js:584)
    at MigrationHelperService.getTenantQueryParam (MigrationHelperService.ts:67)
    at LoginComponent.ngOnInit (loginComponent.ts:32)
    at DebugAppView._View_LoginComponent_Host0.detectChangesInternal (LoginComponent_Host.template.js:34)
    at DebugAppView.AppView.detectChanges (view.ts:243)
    at DebugAppView.detectChanges (view.ts:345)
    at ViewRef_.detectChanges (view_ref.ts:93)
    at eval (downgrade_ng2_adapter.ts:105)
    at Scope.$digest (angular.js:17064)

更进一步,尝试在尝试设置之前访问 this.tenantQueryParamPromiseResolve

try {
    console.log("typof: " +  +  typeof this.tenantQueryParamResolve)
    this.tenantQueryParamPromiseResolve = resolve;
}
catch(err) {
    console.log(err.stack);
}

并得到以下内容:

TypeError: Cannot read property 'tenantQueryParamResolve' of undefined
    at eval (MigrationHelperService.ts:70)
    at new ZoneAwarePromise (zone.js:584)
    at MigrationHelperService.getTenantQueryParam (MigrationHelperService.ts:66)
    at LoginComponent.ngOnInit (loginComponent.ts:32)
    at DebugAppView._View_LoginComponent_Host0.detectChangesInternal (LoginComponent_Host.template.js:34)
    at DebugAppView.AppView.detectChanges (view.ts:243)
    at DebugAppView.detectChanges (view.ts:345)
    at ViewRef_.detectChanges (view_ref.ts:93)
    at eval (downgrade_ng2_adapter.ts:105)
    at Scope.$digest (angular.js:17064)

似乎 this.tenantQueryParamResolve 没有作用域!在TypeScript上读取它似乎与函数相关联,因此它是有意义的。这就是说,如何从promise函数中访问服务 tenantQueryParamResolve ?我已经尝试了所有可能的咒语,我的魔杖是我们的力量!

2 个答案:

答案 0 :(得分:0)

因为您只是声明tenantQueryParamResolve而没有初始化它。如果你在MigrationHelperService的构造函数中添加这样的东西,错误就会消失:

this.tenantQueryParamResolve = (x: string) => { console.log(x); }

答案 1 :(得分:0)

问题正如我所料,范围问题。我通过将 tenantQueryParamResolve 声明为静态来解决它,最终的工作产品是:

import { Injectable } from "@angular/core";

@Injectable()
export class MigrationHelperService {

    /*
     * This is a helper service to be used to capture the route’s tenant query
     * parameter in the NG1 SignInController and make it available in the LoginComponent
     * to enable it to show / hide the tenant form control.
     * TODO: replace it with NG2 route management when the time is right.
     */
    private tenantQueryParam: string;
    private static tenantQueryParamResolve: (x: string) => void;
    private static tenantQueryParamPromise: Promise<string>;

    constructor() {
        MigrationHelperService.tenantQueryParamPromise = new Promise<string>(
            function (resolve) {
                MigrationHelperService.tenantQueryParamResolve = resolve;
            }
        );
    }

    public setTenantQueryParam(tenant: string) {
        this.tenantQueryParam = tenant;
        MigrationHelperService.tenantQueryParamResolve(tenant);
    }

    public static getTenantQueryParam(): Promise<string> {
        return MigrationHelperService.tenantQueryParamPromise;
    }
}
相关问题