【问题标题】:Using Rxjs map and filter together to select country and states from json使用 Rxjs map 和 filter 一起从 json 中选择国家和州
【发布时间】:2020-09-08 20:37:18
【问题描述】:

我有一个包含国家和州的 json 文件(作为示例):

 {
  "countries": [
    {
      "id": 1,
      "name": "United States"
    },
    {
      "id": 2,
      "name": "India"
    }],
  "states": [
    {
      "id": 1,
      "countryId": 1,
      "name": "Alabama"
    },
    {
      "id": 2,
      "countryId": 1,
      "name": "Alaska"
    } ] }

现在我有一个服务可以让国家和州稍后显示在我的下拉列表中:

export class CountriesService {

  constructor(private http: HttpClient) { }

  public getCountries(): Observable<Country[]> {

    return this.http.get<Country[]>("assets/data.json").pipe(map(obj => obj["countries"]));

  }

  public getStates(countryId: number): Observable<State[]> {
    return this.http.get<State[]>("assets/data.json").pipe(
      map(res => res["states"]), 
      map(res => { if (res.countryId === countryId) return res;}));

  }
}

getCountries() 按预期工作,只返回Countries,但我无法从getStates 方法中获得基于countryId 的特定状态。

它什么也不返回。

我做错了什么?

【问题讨论】:

    标签: javascript json angular typescript rxjs


    【解决方案1】:

    您需要稍后在获取数据后对其进行过滤。

    export class CountriesService {
      constructor(private http: HttpClient) { }
    
      public getCountries(): Observable<Country[]> {
        return this.http.get<Country[]>("assets/data.json").pipe(
          map(obj => obj["countries"]),
        );
      }
    
      public getStates(countryId: number): Observable<State[]> {
        return this.http.get<State[]>("assets/data.json").pipe(
          map(res => res["states"]), 
          withLatestFrom(of(countryId)),
          map((id, states) => states.filter(state.countryId === id)),
        );
      }
    }
    

    您也可以将所有内容组合在一起以避免对不同状态的请求,因为它仍然是相同的数据。

    export class CountriesService {
    
      constructor(private http: HttpClient) { }
    
      public getCountriesWithStates(): Observable<Country[]> {
        return this.http.get<Country[]>("assets/data.json").pipe(
          map(data => data.countries.map(country => ({
            ...country,
            states: data.states.filter(state => state.countryId === country.id),
          }))),
        );
      }
    }
    
    service.getCountriesWithStates().subscribe(countries => {
    // countries[0].states[0];
    });
    

    【讨论】:

    • 我无法合并,因为当有人在下拉列表中选择国家/地区时,我需要根据国家/地区获取州。
    • 这只是第二种选择。第一个单独获取它们。
    【解决方案2】:

    虽然 API 调用的结果是一个 observable,但如果是由于 map 函数而不是 observable 数组,它会“发射”一个 observable。因此,您拥有的第二个地图功能并没有达到您的预期。相反,在您的第一张地图中,当您获取州时,您可以使用 JavaScript 数组中的一种方法(称为 filter),将州直至具有所需国家/地区 ID 的州。

    public getStates(countryId: number): Observable<State[]> { return this.http.get<State[]>("assets/data.json").pipe( map(res => res["states"].filter(res => res.countryId === countryId)); }
    

    【讨论】:

    • 完美,只注意 countryId 是一个整数,所以我改为 "res.countryId === +countryId" 以使 "===" 起作用
    猜你喜欢
    • 2021-11-15
    • 2014-08-04
    • 1970-01-01
    • 2013-09-16
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多