如何从值数组中过滤响应?

时间:2019-08-05 18:46:00

标签: angular rxjs

我有一项服务可获取用户的IP信息,以确定他们来自哪个国家/地区以显示本地新闻。我想通过一组支持的国家/地区代码过滤响应,如果不匹配,则返回默认值

我是Rxjs的新手,所以我不确定是否有办法做到这一点,我知道如何使用普通JS中的响应,循环并检查相等性来做到这一点,但我希望这样做,如果可以的话全部集中在一处。

C7

我希望输出在数组中返回受支持的国家代码,如果不在数组中,则会输出默认代码。

编辑:看起来我错过了rxjs过滤器,这是我的解决方案

// A list of around 40 country codes
const supportedCountries = ["ae", "ar", "at", "au", "be", "bg" .....] 



return this.http.get(`${this.ipUrl}/${endpoint}?${this.ipKey}`).pipe(
   map(({ country_code }: any) => country_code),
   filter(code => code === supportedCountries)
);

编辑:PierreDuc提供的更清洁的解决方案

return this.http.get(`${this.ipUrl}/${endpoint}?${this.ipKey}`).pipe(
   map(({ country_code }: any) => country_code),
   map(code => {
      let supportedCode: string = 'gb';
      supportedCountries.forEach(country => {
         if (country === code.toLowerCase()) {
            supportedCode = country;
         }
      });
      return supportedCode;
   })
);

2 个答案:

答案 0 :(得分:2)

要更改可观察的结果,必须使用map。您可以使用includes获得所需的内容。您也可以使其成为一个map函数,但随后必须使用两次toLowerCase()。您发现的任何内容都更清晰。您还可以执行许多其他选择:

return this.http.get(`${this.ipUrl}/${endpoint}?${this.ipKey}`).pipe(
  map(({ country_code }: any) => country_code.toLowerCase())
  map((code) => supportedCountries.includes(code) ? code : 'gb')
);

还要尝试通过键入所有对象来避免使用any

答案 1 :(得分:0)

完成subscribing之后或在调用方法中,您是pipe(...).subscribe()吗?

正如PierreDuc所说的那样,您也不想使用any,因为如果输入的内容不安全,并且在以后进行重构时会给自己带来麻烦。始终使用界面(模型),并以智能感知为指导。

以下是对我有用的示例:

export interface CountryCode {
  country_code: string[]
}

const supportedCode = 'gb'

getCountryCodes(endpoint: string): Observable<CountyCode> {
    return this.http.get(`${this.ipUrl}/${endpoint}?${this.ipKey}`).pipe(
       map(country_code => country_code),
       filter(codes => codes === supportedCode)
    );
}

但是,实际上,后端应该带回您需要在前端使用的所有数据,并且将阻止您在前端进行过滤。如果希望,您不需要filter(codes => codes === supportedCode),只需将其放在组件中即可:

this.getCountryCodes(this.endPoint)
.pipe(
tap(codes => this.countryCodes = codes)
).subscribe();