首页 > 解决方案 > 缺少元素时如何防止地图失败

问题描述

有没有办法让映射更能证明失败?当数据通过以下代码进入时,我实现了映射。

getSurveyRequest(surveyId: string) {
        return this.api.get({endpoint: '/survey/request/' + surveyId})
            .pipe(
                map(res => res as IApiResponseBody<ISurvey[]>),
                map((res: IApiResponseBody) => { res.Data = SurveyRequestService.adaptMainSurveyList(res.Data);
                                                 console.log(res.Data);
                                                 if ( res.Success === true) {
                                                        return res.Data;
                                                    }
                                                 return null;
            })
            );
    }

这是我的静态适配器

static adaptMainSurveyList(surveylist): ISurvey {
        if (surveylist) {
            return {
                docId: surveylist.docId,
                firstName: surveylist.contact.fname,
                lastName: surveylist.contact.lname,
                email: surveylist.contact.email,
                phone: surveylist.contact.phone,
                address1: surveylist.property.address1,
                address2: surveylist.property.address2,
                city: surveylist.property.city,
                state: surveylist.property.state,
                zip: surveylist.property.zip,
                status: surveylist.property.status
            };
        }

    }

一切正常,但是例如当数据元素中没有联系人或属性元素时,它会完全失败,当有空的联系人和属性元素时,它会再次工作。所以我不确定为什么会发生这种情况,以及我可以做些什么来使代码更健壮,所以如果 api 返回一些格式错误的数据,它不会导致大问题。

标签: angular

解决方案


您正在寻找的是一种安全树遍历的方法,不幸的是,Typescript 不支持开箱即用的方法来执行简单而干净的安全树遍历。

当然,您可以对几条内联三元语句进行逻辑检查。请参阅下面的示例,

static adaptMainSurveyList(surveylist): ISurvey {
  if (surveylist) {
    return {
      docId:     surveylist.docId,
      firstName: surveylist.contact  ? surveylist.contact.fname     : null,
      lastName:  surveylist.contact  ? surveylist.contact.lname     : null,
      email:     surveylist.contact  ? surveylist.contact.email     : null,
      phone:     surveylist.contact  ? surveylist.contact.phone     : null,
      address1:  surveylist.property ? surveylist.property.address1 : null,
      address2:  surveylist.property ? surveylist.property.address2 : null,
      city:      surveylist.property ? surveylist.property.city     : null,
      state:     surveylist.property ? surveylist.property.state    : null,
      zip:       surveylist.property ? surveylist.property.zip      : null,
      status:    surveylist.property ? surveylist.property.status   : null
    };
  }
}

这可能很好,并且可能是您使用当前数据结构可以获得的最佳效果。不幸的是,如果您需要降低一到两级以上,您的三元运算符最终会遇到几个条件,而且看起来很糟糕。

但是,如果您不介意使用第三方库,lodash 有一个可以很好地完成安全树遍历的函数,称为_.get(object, path, [defaultValue]).

获取对象路径的值。如果解析的值未定义,则在其位置返回 defaultValue。

自 3.7.0 起

论据

  • 对象(Object):要查询的对象。
  • path (Array|string): 要获取的属性的路径。
  • [defaultValue] (*):为未定义的解析值返回的值。

Returns (*):返回解析后的值。

使用 lodash,您可以修改您的构造函数,如下所示:

static adaptMainSurveyList(surveylist): ISurvey {
        if (surveylist) {
            return {
                docId:     _.get(surveylist, "docId", null),
                firstName: _.get(surveylist, "contact.fname", null),
                lastName:  _.get(surveylist, "contact.lname", null),
                email:     _.get(surveylist, "contact.email", null),
                phone:     _.get(surveylist, "contact.phone", null),
                address1:  _.get(surveylist, "property.address1", null),
                address2:  _.get(surveylist, "property.address2", null),
                city:      _.get(surveylist, "property.city", null),
                state:     _.get(surveylist, "property.state", null),
                zip:       _.get(surveylist, "property.zip", null),
                status:    _.get(surveylist, "status", null)
            };
        }
    }

作为旁注,您实际上可以在 Angular 的模板中使用插值来执行此操作。Angular 模板中的Elvis 运算符{{a?.b?.c?.d}}是模板安全树遍历的有效方法,但它在 Typescript 中不起作用。


推荐阅读