typescript HTTP调用中的Angular未定义对象

6tqwzwtp  于 2023-04-07  发布在  TypeScript
关注(0)|答案(3)|浏览(107)

我有一个问题,可能是容易和明显的大多数你,但我花了很多时间在这一点上,我决定,我需要帮助。
我正在从www.example.com构建一个简单的项目frontendmentor.io,并被一个功能卡住了。
一个接一个:
应用程序的第一步,有HTTP请求从服务器获取数据并显示。我使用主组件获取数据,并将数据作为列表元素传递给子组件。单击单个元素后,会导航到另一个组件,其中包含更多详细信息。在该组件中,我首先从url获取参数,然后再进行一次请求。但不是完整的元素列表,我只从服务器接收到一个元素。
现在显示必须继续。我的模板不显示任何数据,我不知道什么是错的。
数据模型模型:

export interface Country {
    borders: string[];
    capital: string;
    cca3: string;
    currencies: {
        [key: string]: {
            name: string;
            symbol: string;
        }
    }
    flags: {
        alt: string;
        png: string;
        svg: string;
    };
    languages: {
        [key: string]: string;
    };
    name: {
        common: string;
        nativeName: {
            [key: string]: {
                common: string;
            }
        };
    };
    population: number;
    region: string;
    subregion: string;
    tld: string;   
}

售后服务:

export class CountriesService {
  constructor(private http: HttpClient){}

  getCountries(): Observable<Country[]> {
    return this.http.get<Country[]>('https://restcountries.com/v3.1/independent?status=true&fields=name,nativeName,population,region,subregion,capital,tld,currencies,languages,borders,flags,cca3');
  }

  getSingleCountry(countryName: string): Observable<Country> {
    return this.http.get<Country>('https://restcountries.com/v3.1/name/'+countryName+'?fullText=true&fields=name,nativeName,population,region,subregion,capital,tld,currencies,languages,borders,flags,cca3');
  }
}

以及组件.ts文件的一部分:

export class CountryDetailComponent implements OnInit{
    param!: string;
    country!: Country;

    constructor(
        private route: ActivatedRoute,
        private cs: CountriesService
    ) {}

    ngOnInit(): void {
        this.route.params.subscribe((params) => {
            this.param = params['country'];
        });

        this.cs.getSingleCountry(this.param).subscribe(result => {
            this.country = result;
            console.log(this.country);
        });

    }

在模板中显示我使用插值。对我来说最奇怪的事情是,在控制台对象是正确的,但所有的模板是空的。我不知道我做错了什么。
我也试过只做一个请求,所有对象的元素,并保持到一个服务,并在整个应用程序中使用这个列表的全局istance,但我有一些麻烦,我决定做更简单的解决方案
编辑:Html组件的模板代码:

<div class="country-detail content-wrapper">
<div class="container">
    <div class="button-section">
        <button (click)="returnToList()">
            <fa-icon [icon]="faArrow"></fa-icon> Back
        </button>
    </div>
    <div class="details-section">
        <div class="details-section__flag">
            <img src="{{country.flags.svg}}" alt="">
        </div>
        <div class="details-section__content">
            <h2>{{country.name.common}}</h2>
            <div class="details-section__content--middle">
                <div class="left">
                    <p><span class="bold">Native Name: </span>{{nativeNameArray}}</p>
                    <p><span class="bold">Population: </span>{{country.population}}</p>
                    <p><span class="bold">Region: </span>{{country.region}}</p>
                    <p><span class="bold">Sub Region: </span>{{country.subregion}}</p>
                    <p><span class="bold">Capital: </span>{{country.capital}}</p>
                </div>
                <div class="right">
                    <p><span class="bold">Top Level Domain: </span>{{country.tld}}</p>
                    <p><span class="bold">Currencies: </span>{{currencyArray}}</p>
                    <p><span class="bold">Languages: </span>{{languageArray}}</p>
                </div>
            </div>
            <div class="details-section__content--bottom">
                <p><span class="bold">Border Countries: </span><span class="border" *ngFor="let border of borderCountries" (click)="navigateToCountry(border)">{{border}} </span></p>
            </div>
        </div>
    </div>
</div>

请不要注意类名或附加变量或函数-有一堆实验。

9bfwbjaz

9bfwbjaz1#

正常,http调用后触发路由事件
用这个逻辑来代替

export class CountryDetailComponent implements OnInit{
    protected country?: Country;

    constructor(
        private _activatedRoute: ActivatedRoute,
        private _countriesService: CountriesService
    ) {}

    ngOnInit(): void {
        this.route.params.pipe(
            map((params) => params['country']),
            switchMap((country: string) => this._countriesService.getSingleCountry(country))
        ).subscribe(country => {
            this.country = country;
        });

    }
}
1sbrub3j

1sbrub3j2#

我的假设是,如果没有一个repro,您将尝试并行执行两个异步调用-首先,获取参数,然后加载国家/地区的详细信息。
1.更改CountryDetails的模板(我已添加异步订阅)

<div class="country-detail content-wrapper">
  <div class="container" *ngIf="country$ | async as country">
      <div class="details-section">

1.根据路由信息初始化国家/地区

export class CountryDetailComponent implements OnInit {
  country$: Observable<Country>;

  constructor(
      private route: ActivatedRoute,
      private cs: CountriesService
  ) {
    this.country$ = this.route.params.pipe(
      switchMap(param => this.cs.getSingleCountry(param['country']) )
    )
  }
}

如果不起作用,请修改此stackblitz以重现问题

k5ifujac

k5ifujac3#

感谢大家的帮助,我自己找到了解决方案。问题是,我从服务器收到的响应是1个元素数组而不是单个对象。最简单的方法是在服务中将observable类型更改为Country[]并分配result[0]

相关问题