javascript - 在 Angular 应用程序中的网络请求之前对空对象使用条件检查

标签 javascript angular typescript

我有一个函数可以接收过滤器值并在我的 Angular 应用程序中传递网络请求。因为我遇到了在过滤器到达之前发出网络请求的问题,所以我尝试设置一些条件检查,以便在过滤器值可用之前不发出网络请求。这不是理想的解决方案,但我正在尝试在短时间内让某些东西发挥作用(目前)。

这是我的代码。首先,我设置一个函数来检查对象是否为空。我这样做是因为我只想在拥有非空对象时触发网络请求。一旦应用了过滤器值,该对象将非空。代码如下:

isEmptyObj(obj) {
    return Object.keys(obj).length === 0;
}

public async onFilterReceived(values) {
    let filters = {};

    if (!values) return;

    if (values) {
        filters = values;
    }

    this.route.params.subscribe(
        (params: any) => {
            this.page = params['page'];
        }
    );

    let fn = resRecordsData => {
        this.records = resRecordsData;
    };

    // Make request IF filters is NOT empty object (i.e. it has values)
    if (!this.isEmptyObj(filters)) {
        console.log('filter values within cond call: ', filters); // should not be empty
        console.log('firstName within cond call: ', filters['firstName']); // should not be empty in this case as I selected a firstName value
        console.log('should be false: ', this.isEmptyObj(filters)); // should be false
        this.streamFiltersService.getByFilters(
            this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
            this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
            this.branch = filters['branch'], fn);
    }
}

显然这没有按预期工作。当我查看条件部分中记录到控制台的内容时,我看到“filters”和“firstName”为空值。换句话说,我的条件检查没有按我的预期工作。我在这里缺少什么?我该如何以不同的方式处理这个问题,以便只有在获得值后才发出网络请求?

顺便说一下,当我console.log values时,这就是我得到的:

{zip: Array(0), firstName: Array(0), lastName: Array(0), language: Array(0), location: Array(0), …}

顺便说一句,我使用的早期控制台日志表明,最初 filters 是一个空对象。只是我将values分配给filters,它就不再是一个空对象了。

那么,为什么我在网络请求之前的条件检查按预期工作?

在 if 条件中我看到这个 console.log:

filter values within cond call:  {zip: Array(0), firstName: Array(0), lastName: Array(0), language: Array(0), location: Array(0), …}

根据我上面的代码帮助我理解这是如何发生的。

最佳答案

第一个问题是检查键的方法 isEmptyObj(obj) 无法按您的预期工作。这是因为您提供的示例:

{zip: Array(0), firstName: Array(0), lastName: Array(0), language: Array(0), location: Array(0), …}

尽管它只是空数组,但仍然具有键,因此该方法 isEmptyObj 将为该示例值返回 false。唯一一次返回 false 的情况是对于普通的空对象 {}

function isEmptyObj(obj) {
  return Object.keys(obj).length === 0;
}

console.log(isEmptyObj({}));
console.log(isEmptyObj({ zips: [] }));

因此将其更改为基于长度过滤“虚假”值的位置:

function isEmptyObj(obj) {
  return Object.keys(obj).map(key => obj[key]).filter(v => v.length > 0).length === 0;
}

console.log(isEmptyObj({ }));
console.log(isEmptyObj({ zip: [] }));

下一期是onFilterReceived的流程。它不需要是一个async方法,而且this.route.params.subscribe()实际上总是在方法中的其余代码之后执行。尝试以下操作,至少将所有内容移至 subscribe() 中。请记住,您需要 subscribe()HTTP 调用才能实际执行它们:

public onFilterReceived(values) {
    let filters = {};

    if (!values) return;

    if (values) {
        filters = values;
    }

    this.route.params.subscribe((params: any) => {
        this.page = params['page'];

        let fn = resRecordsData => (this.records = resRecordsData);

        // Make request IF filters is NOT empty (i.e. it has values)
        if (!this.isEmptyObj(filters)) {
          this.streamFiltersService.getByFilters(
            this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'],
            this.location = filters['location'],
            this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
            this.branch = filters['branch'],
            fn
          )
          .subscribe(results => console.log(results));
        }
      });
   );
}

您可以使用运算符,例如 switchMap , takeWhile ,和tap简化 Observable 部分:

import { switchMap, takeWhile, tap } from 'rxjs/operators';

// ..

public onFilterReceived(values) {
    let filters = {};

    if (!values) return;

    if (values) {
        filters = values;
    }

    this.route.params.pipe(
        tap((params: any) => this.page = params['page']),
        takeWhile(_ => !this.isEmptyObj(filters)),
        switchMap((params: any) => {
            let fn = resRecordsData => (this.records = resRecordsData);

            return this.streamFiltersService.getByFilters(
                this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'],
                this.location = filters['location'],
                this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
                this.branch = filters['branch'],
                fn
            );
        });
    ).subscribe(results => console.log(results));
}

希望有帮助!

关于javascript - 在 Angular 应用程序中的网络请求之前对空对象使用条件检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52544391/

相关文章:

javascript - 相同字符串优化

javascript - 如何使用 lodash get 处理空值

angular - 如何在Angular 2.0中为Dart定义子路线

javascript - 如何将输入文件对象序列化为 JSON?

html - 为什么媒体查询在 Angular 8 中不起作用

Angular 4 DI : wait for method completion

angular - 数据源未在 ag 网格中执行

javascript - 带有react-redux组件的React typescript需要所有传递的props

javascript - 如何使用实现接口(interface)制作 Typescript 枚举

javascript - 找到包含文本和一些动态 html 的 div