Konrad Viltersten
Konrad Viltersten

Reputation: 39068

It feels like there's a third scope (besides public and private) in Angular but there isn't

As far I can read the documentation there's only public and private as scopes in TypeScript. However, when I attempt the following exercise, I get different results, as if the variable environment isn't visible to the markup unless declared (publicly or privately).

<div class="text-section">
  Name is: {{environment.shazoo}}.
</div>
import { environment } from "../../../../environments/environment";
...
@Component({ ... })
export class DemoComponent implements OnInit {
  constructor(private builder: FormBuilder) { ... }
  ...
  private environment = environment;
}

The above example results in the text hazaa being displayed. However, if I comment out the line assigning the imported environment instance to the locally declared one, the text vanishes.

import { environment } from "../../../../environments/environment";
...
@Component({ ... })
export class DemoComponent implements OnInit {
  constructor(private builder: FormBuilder) { ... }
  ...
  // private environment = environment;
}

The way I figure, if the imported instance is visible in the code but not in the markup, there's a third level of scoping, whatever that might be (some kind of secludedly private thingy). But I hardly think that it's the case in reality. What am I missing?

Upvotes: 1

Views: 73

Answers (1)

Estus Flask
Estus Flask

Reputation: 222319

It seems that you're confusing TypeScript visibility with JavaScript contexts and variable scopes.

private and public are access modifiers and affect only type checking at compilation stage and are optional (except the case when they are used as constructor, where they are also implicitly assign a parameter as class property).

The meaning behind private environment = ... is that this.environment = ... happens in constructor under the hood. You can check in transpiled code that

export class DemoComponent implements OnInit {
  ...
  environment = environment;
}

results in this.environment = environment (public access modifier is optional here).

it's not possible to use imported environment variable (which is local to component module where it was imported ) in another place (compiled template), unless it was made available to the place where it should be used (template compiler), e.g. by assigning it to something it has access to (class property). This is suggested by the way how JavaScript works and isn't specific to Angular or TypeScript.

{{environment}} really means that environment property is being read from component class instance. Since template syntax is DSL that is defined by Angular compiler, this is available there but was made optional for brevity:

{{environment === this.environment}} is true

Finally, all component properties that are used in templates should be public, i.e. should not have private or protected access modifier. This is required for Angular AoT compilation.

Upvotes: 3

Related Questions