【问题标题】:Reading an environment variable before it is defined [duplicate]在定义之前读取环境变量[重复]
【发布时间】:2019-11-02 03:30:50
【问题描述】:

我正在使用环境变量来读取 JSON 中的内容并显示在我的 HTML 中。我的问题是我的 HTML 在 .ts 中定义之前尝试读取环境变量,因此出现错误。

我目前正在ngOnit() 中定义变量,但这给了我一个错误。我正在使用httpclient 来读取JSON(从服务器),显然正在发生的事情是在httpclient 获得数据之前在HTML 中读取变量。

HTML

<p>Player One is: {{ id.playerone }} </p>

.ts

import { HttpClient } from '@angular/common/http';

export class ApComponent implements OnInit {
    id: any = [];

    constructor(private httpService: HttpClient) { }
    ngOnInit() {
        this.httpService.get('http://server/info.json').subscribe(
            result => {
            this.id = result;
            },
            error => {
                console.log('Error Occured', error);
            }
        );
    }
}

JSON

{  
   "playerone":"ajf806",
   "playertwo":"hof934"
}

我得到了Player One is: ajf806 的预期输出,但我在控制台中也得到了一个错误:

错误类型错误:无法读取未定义的属性“0”。

它确实有效,我得到了输出,但我不想在控制台中出现错误。有没有办法延迟 HTML 读取环境变量,直到 JSON 被读取?

【问题讨论】:

  • 您确定这不是因为您已将 id 声明为数组,但您从服务器返回的不是数组吗?有问题的错误通常发生在您尝试索引空数组时......(我的意思是空的,未初始化)
  • @StephenByrne 当我不将其声明为数组时,id: any;。我收到此错误:ERROR TypeError: Cannot read property 'playerone' of undefined.
  • 最简单的方法是在你的标签

    上放一个 *ngIf="id" 或者你可以看看在 Angular 中预取数据(路由解析器)是如何工作的。您还可以使用@user2216584 所述的安全运算符。

  • @Dritz 只使用id; 而不是id: any = []; 并且还使用安全导航运算符&lt;p&gt;Player One is: {{ id?.playerone }}
  • 为什么在没有得到值的情况下还要显示值。你可以设置 *ngIf="id",当你得到你的值时,你会在 dom 中渲染那个 p。

标签: javascript html angular


【解决方案1】:

像这样改变你的变量:

id: any;

还可以像这样更改您的模板:

<p>Player One is: {{ id?.playerone }} </p>

上述代码的另一个版本[更好一点]:

import { HttpClient } from '@angular/common/http';

export class ApComponent implements OnInit {
    id$: Observable<any>;

    constructor(private httpService: HttpClient) { }
    ngOnInit() {
        this.id$ = this.httpService.get('http://server/info.json')
                       .pipe(
                          catchError((error) => {
                             //handle your error
                             console.log(error);
                          })
                        )
        );
    }
}

现在更改您的模板以使用 async 管道,如下所示:

<ng-conatiner *ngIf="(id$ | async) as id">
 <p>Player One is: {{ id.playerone }} </p>
</ng-container>

注意 - 您没有订阅组件中的 observable。 async pipe 负责订阅管理 [即订阅/取消订阅。]。

【讨论】:

  • 太棒了!这消除了错误。您能否确认这是一个正确的解决方案,而不仅仅是一个“粗略”的解决方案来消除错误?谢谢
  • @Dritz 使用他指定的安全导航运算符,也只使用id; 而不是id: any = []; 其他方式是在加载组件之前使用resolve加载数据,但仍然需要安全导航运算符
  • @Dritz 查看我的更新答案以获得更好的版本。
猜你喜欢
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
  • 2019-07-27
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2015-09-21
相关资源
最近更新 更多