错误未定义prop(需要帮助进行调试)后,整个应用会停止运行

时间:2018-07-30 12:51:10

标签: javascript angular typescript debugging

错误的再现:

1。。这里有一些广告客户(我们的客户),我们针对这些广告客户执行一些营销活动。

2。。当您单击某个广告商的“广告系列”按钮时。

结果:您在“广告系列”页面上被重定向,并且所有    所选广告客户的广告系列。

3。,但是在单击“广告系列”按钮以在广告系列上重定向您后,有时并非总是,得到错误提示“名称”为 未定义。 屏幕截图: enter image description here

这是单击“广告系列”按钮后执行的主要逻辑。
header.component.ts:

    @Input() advertiserId: string;
    @Input() advertiserIoId: string;
    @Input() campaignId: string;

    public advertiserDto: AdvertiserDto;

    // This prop have value which is undefined in the moment of rendering: "AdvertiserIoDto"
    public advertiserIoDto: AdvertiserIoDto;
    public campaignDto: CampaignDto;

    constructor(private advertiserModel: AdvertiserModel,
                private advertiserIoModel: AdvertiserIoModel,
                private campaignModel: CampaignModel) {
    }

     ngOnChanges() {
        this.getAdvertiserDto();
        this.getAdvertiserDtoData();
        this.getAdvertiserIoDto();

        // here is the problem getAdvertiserIoDtoData()
        this.getAdvertiserIoDtoData();
        this.getCampaignDto();
        this.getCampaignDtoData();
    }

    private getAdvertiserDto(): void {
        this.advertiserDto = this.advertiserModel.getDto(this.advertiserId);
    }

    private getAdvertiserIoDto(): void {
        this.advertiserIoDto = this.advertiserIoModel.getDto(this.advertiserIoId, this.advertiserId);
    }

    private getCampaignDto(): void {
        this.campaignDto = this.campaignModel.getDto(this.campaignId, this.advertiserId, this.advertiserIoId);
    }

    private getAdvertiserDtoData(): void {
        this.advertiserModel
            .getDtoData(this.advertiserDto)
            .catch(error => console.log(error))
    }

    private getAdvertiserIoDtoData(): void {
        this.advertiserIoModel
            .getDtoData(this.advertiserIoDto)
            .catch(error => console.log(error))
    }

    private getCampaignDtoData(): void {
        this.campaignModel
            .getDtoData(this.campaignDto)
            .catch(error => console.log(error))
    }

页眉模板-部分({{advertiserIoDto.dtoData.name}})-未定义的dtoData.name:

<span *ngIf="campaignDto.isLoaded === true"
      [routerLink]="['/private/advertiser/' + advertiserId + '/advertiserIo/' + advertiserIoId]"
      class="nano-breadcrumb-item">
    {{ advertiserIoDto.dtoData.name }}
</span>

一件重要的事情,如果您比较“ ngOnChanges”和“ Browser”中的执行顺序,  您会看到“ getAdvertiserDtoData()”在“ getCampaignDtoData()”之前启动,但随后执行。 我认为那是问题。

截屏: enter image description here

有什么办法解决这个问题吗?

错误跟踪:

NanoCampaignHeaderComponent.html:16 ERROR TypeError: Cannot read property 'name' of undefined
at Object.eval [as updateRenderer] (NanoCampaignHeaderComponent.html:16)
at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:13105)
at checkAndUpdateView (core.es5.js:12256)
at callViewAction (core.es5.js:12599)
at execEmbeddedViewsAction (core.es5.js:12557)
at checkAndUpdateView (core.es5.js:12252)
at callViewAction (core.es5.js:12599)
at execComponentViewsAction (core.es5.js:12531)
at checkAndUpdateView (core.es5.js:12257)
at callViewAction (core.es5.js:12599)

1 个答案:

答案 0 :(得分:1)

在我的评论之后:在Javascript中,您可以按照返回值的方式编写条件。

例如:

let obj = { a: true, b: true };
console.log(obj.a && obj.b);

您认为会流行什么?可能是true

let obj = { a: true, b: true };
console.log(obj.a && obj.b);

实际上,它不显示布尔值的结果:它显示条件的最后一个值。这与字符串非常吻合:

let obj = { a: 'A', b: 'B' };
console.log(obj.a && obj.b);

现在,您可能会说它应该再次显示true(因为有truthy and falsy个值)。但是请检查:

let obj = { a: 'A', b: 'B' };
console.log(obj.a && obj.b);

显示

B。如前所述,返回条件的最后一个值

我为什么要向你解释呢?仅仅是因为当您编写此内容

advertiserIoDto?.dtoData?.name

这实际上是此操作的快捷方式

advertiserIoDto && advertiserIoDto.dtoData && advertiserIoDto.dtoData.name

如果您理解的话,这意味着advertiserIoDto.dtoData.name将在最后返回。

然后,您有一个OR语句:

{{ advertiserIoDto?.dtoData?.name || '' }}

这又与这种行为有关:当所有值均为假时,将返回OR语句。让我给你看一个例子:

let obj = { a: '', b: '' };
console.log(obj.a && obj.b || 'No value');

由于''是虚假的,因此两个条件都不满足:返回的代码为OR语句。

这与Angular中的原理非常相似:您只需将HTML中的安全导航?作为快捷方式即可。