簡體   English   中英

如何將一個 Observable 對象數組轉換為該對象數組中數據的 Observable?

[英]How do you turn an Observable array of objects, into an Observable of the data inside that array of objects?

我收到此錯誤:

類型“Observable<Country[]>”不可分配給類型“Observable”。 類型“Country[]”缺少類型“Country”中的以下屬性:name、tld、alpha2Code、alpha3Code 和 20 more.ts(2322


我認為這是因為我到達的端點返回一個數組,其中包含一個對象。 這是一個例子。

https://restcountries.com/v3.1/name/peru


這是我無法開始工作的代碼。 它拒絕編譯並給我上面發布的錯誤。

export class DetailsComponent implements OnInit {
  country$!: Observable<Country>
  countryBorders$!: Observable<Country[]>

  constructor(private apiService: ApiService, private activatedRoute: ActivatedRoute){}

  ngOnInit(): void {
    this.activatedRoute.params.subscribe((params) => {
      let countryName = params['country'];
      this.country$ = this.apiService.getCountryByName(countryName)
    });
    };
  }

getCountryByName() 方法如下所示:

  getCountryByName(name: string) {
    return this.http
      .get<Country[]>(`${this.api}/name/${name}`)
  }

我如何獲取“this.country$”變量/可觀察/主題(idk 技術上是什么),以保存 HTTP 請求返回的數組內的對象內的數據?

我以為我可以將值映射到數組之外,但這也不起作用:

  ngOnInit(): void {
    this.activatedRoute.params.subscribe((params) => {
      let countryName = params['country'];
      this.country$ = this.apiService.getCountryByName(countryName).pipe(map(([info])=>return info)
    });
    };
  }

當我這樣做時,我沒有得到錯誤,但是這個模板:

<div *ngIf="country$ | async as country">
  <h1>{{country$}}</h1>
</div>

渲染

[object Object]

...就像頁面上的 h1 字面意思只是說“[object Object]”


我究竟做錯了什么? 我需要使用什么運算符組合來將 'Observable<Country[]>' 轉換為 'Observable<Country' 以便我可以在這樣的 html 模板中呈現它?

  <div>
    <p><strong>Native Name: </strong>{{ country$.name.nativeName }}</p> 
    <p><strong>Population: </strong>{{ country$.population | number : '0.0' }}</p> 
    <p><strong>Region: </strong>{{ country$.region }}</p> 
    <p><strong>Sub Region: </strong>{{ country$.subregion }}</p> 
    <p><strong>Capital: </strong>{{ country$.capital }}</p></div>
    <div> 
      <p><strong>Top Level Domain: </strong>{{ country$.tld }}</p> 
      <p><strong>Currencies: </strong>{{ country$.currencies }}</p> 
      <p><strong>Languages: </strong>{{ country$.languages }}</p>
   </div>
</div>

這是與答案相關的界面:

export interface Country {
  name: Name; //---
  tld: string[]; //---
  cca2: string;
  ccn3: string;
  cca3: string;
  cioc: string;
  independant: Boolean
  status: string;
  unMember: Boolean;
  currencies: Currency[]; //---
  idd: Idd;
  capital: string[]; //---
  altSpellings: string[];
  region: string;
  subregion: string; //---
  languages: any; //---
  translations: any;
  latlng: number[];
  landlocked: Boolean;
  borders: string[]; //---
  area: number;
  demonyms: any;
  flag: string;
  maps: Maps;
  population: number; //---
  gini: any;
  fifa: string;
  car: any;
  timezones: string[];
  continents: string[];
  flags: Flags;
  coatOfArms: COA;
  startOfWeek: string;
  capitalInfo: Capital;
  postalCode: Postal;
  // nativeName: string;
  // numericCode: string;
  // regionalBlocs: RegionalBloc[];
}

看起來您的getCountryByName方法中存在輸入問題。 而不是.get<Country[]> ,它應該是.get<Country>

getCountryByName(name: string) {
  return this.http
    .get<Country>(`${this.api}/name/${name}`)
}

RestCountries API 返回具有數組類型的響應。 您可以通過map rxjs 提取數組的第一個元素來實現。

getCountryByName(name: string): Observable<Country> {
  return this.http
    .get<Country[]>(`${this.api}/name/${name}`)
    .pipe(map((x) => x[0]));
}

您從country$ Observable 中提取屬性的方式不正確。 您應該尋找一個async管道作為您在問題中取得的成就。

<div *ngIf="country$ | async as country">
  <div>
    <p><strong>Native Name: </strong>{{ country.name.nativeName | json }}</p>
    <p>
      <strong>Population: </strong>{{ country.population | number: '0.0' }}
    </p>
    <p><strong>Region: </strong>{{ country.region }}</p>
    <p><strong>Sub Region: </strong>{{ country.subregion }}</p>
    <p><strong>Capital: </strong>{{ country.capital }}</p>
  </div>
  <div>
    <p><strong>Top Level Domain: </strong>{{ country.tld }}</p>
    <p><strong>Currencies: </strong>{{ country.currencies }}</p>
    <p><strong>Languages: </strong>{{ country.languages }}</p>
  </div>
</div>

演示 @ StackBlitz

這是正確的格式:

export class DetailsComponent implements OnInit {
  country$!: Observable<Country>
  countryBorders$!: Observable<Country[]>

  constructor(private apiService: ApiService, private activatedRoute: ActivatedRoute){}

  ngOnInit(): void {
    this.activatedRoute.params.subscribe((params) => {
      let countryName = params['country'];
      this.country$ = this.apiService.getCountryByName(countryName).pipe(map(([info])=>{return info}))
    });
    };
  }

我做對了。 但在模板中使用:

<div *ngIf="country$ | async as country">
  <h1>{{country.name.common}}</h1>
</div>

不是

<div *ngIf="country$ | async as country">
  <h1>{{country$.name.common}}</h1>
</div>

愚蠢的錯誤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM