代码之家  ›  专栏  ›  技术社区  ›  James Delaney

未定义属性错误后整个应用程序停止(需要帮助调试)

  •  0
  • James Delaney  · 技术社区  · 6 年前

    虫子繁殖:

    有一个广告商(我们的客户)的名单,我们执行一些营销活动。

    当你点击某个广告商的“活动”按钮时。

    结果: 您在“活动”页面上被重定向,并且 被选中的广告商的活动。

    三。 但在点击“活动”按钮重新引导你的活动后,有些时候 不总是 ,获取错误属性“name”是 未定义。 截图: enter image description here

    这是点击“活动”按钮后执行的主要逻辑。
    标题.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 回复  |  直到 6 年前
        1
  •  1
  •   user4676340user4676340    6 年前

    以下是我的评论:在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);
    

    现在,你可以说它应该显示 真的 再次(因为 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 || '' }}
    

    这与此行为再次相关:当所有值都是falsy时,返回OR语句。我给你举个例子:

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

    自从 '' 为falsy,两个条件都未满:返回的代码是或语句。

    这在角度上是同样的原理:你只要有安全的导航 ? 以HTML作为快捷方式。