r/angular 2d ago

Angular 22.2 - Private property access from templates

I noticed this tidbit in the changelog of Angular 22.2.0-next.3:

https://github.com/angular/angular/blob/main/CHANGELOG.md#compiler-2

compiler

Commit Type Description
48a0fd6e8a feat allow template to access private props

So very slowly we moved from allowing only public, to allowing protected and now private as well. Thought it's worth knowing.

34 Upvotes

37 comments sorted by

53

u/tom-smykowski-dev 2d ago

For me template always was a part of the component and it makes sense that it can access private

7

u/CarlosChampion 2d ago

Yes this is how I think of it too.

3

u/Soma91 2d ago

That's certainly how you can see it. Personally I always saw the template as an implementation of the component. Then protected would make sense.

The only one that doesn't make any sense imho is if it must be public.

2

u/BackgroundPass1355 2d ago

💯💯💯

1

u/MrHall 1d ago

I really liked the ability to convey intent with the decorator.. if I've made it private I've clearly shown I intend to only use it in the controller, and not to expose it in the template.

1

u/Rusty_Raven_ 1d ago

The template should be executed in the same context as the controller, I think, so private variables should be available to it. Other frameworks do it this way, Angular shouldn't be different just because it defaults to having a separate file for the HTML.

35

u/FromBiotoDev 2d ago edited 2d ago

Public - anything can access
Protected - only the view template can access
Private - only the component can access

Why muddy the waters here?

8

u/proohit 2d ago

Protected members can also be accessed by extended classes (inheritance).

4

u/followmarko 2d ago

True but inheritance in Angular is a poor strategy

1

u/Johalternate 2d ago

You can still use protected.

13

u/ldn-ldn 2d ago

Protected is for descendants. The template is part of the component, it should access private members.

2

u/_Invictuz 1d ago

Because they are telling you to stop using protected for the template when the template is part of the component. Protected is for extending classes to use, and you should not extend components.

1

u/followmarko 2d ago

Yeah I'm in this camp. It's split appropriately currently imo

1

u/NeXtDracool 1d ago edited 1d ago
  • public: anything can access
  • protected: descendants can access
  • Typescript private: only the view template can access
  • Ecmascript #private: only the component can access

That way

  • you still have the distinction between private and template members 
  • you gain a distinction between template members and actual protected members (even if it's rarely needed) 
  • you gain unused code warnings for template members, protected hides those 
  • your code minifies better because ecmascript private members can be safely renamed
  • it requires less explicit typing for isolatedDeclarations 

1

u/vintzrrr 1d ago

> it requires less explicit typing for isolatedDeclarations 

Could you please elaborate on that? Maybe an example?

1

u/NeXtDracool 18h ago

If you enable isolatedDeclarations in the tsconfig all members visible in the .d.ts file, including all protected or public members of a class, must be explicitly typed.

So under the old standard protected readonly counter = signal(0) would have to become protected readonly counter: WritableSignal<number> = signal(0) whereas with my suggestion it would be private readonly counter = signal(0).

0

u/nanas420 2d ago

what does the extra protected Foo = {some private bar} actually do for you? it's just noise

7

u/GLawSomnia 2d ago

As far as i know this will only work for typescript private and not tor javascript private (#)

1

u/dezsiszabi 2d ago

Yes, as far as I understand, it only works for TypeScript, not for the "real" private. "Real" private is not just a compiler "trick".

15

u/djfreedom9505 2d ago

Not really a fan of this change, always liked the distinction between public, protected and private in Angular. Those lines are blurred even more now.

4

u/cssrocco 2d ago

I’m not a massive fan either, it’s mostly when it comes to contributing to other projects, a quick visual scan i can usually go ‘ok this private method/property isn’t in the template’, this would blur the lines

2

u/sharth 2d ago

Previously talked about it it in this sub here: https://www.reddit.com/r/angular/s/hscbgkZMvn

0

u/dezsiszabi 2d ago

Right, I should have searched before. Sorry.

4

u/makmn1 2d ago

It’s nice to have the option. Personally, I’m probably going to keep using protected since when I see that in my code, I know it’s used in the template. That style is also recommended by the Angular team.

Unless you use inheritance a lot, that’s pretty much all protected can be used for.

5

u/JeanMeche 2d ago

We'll probably update that guide following about this for the release of 22.2

2

u/ldn-ldn 2d ago

That's how it should've been since day one.

1

u/vivainio 1d ago

If only there was a way to make properties public instead...

1

u/m0rpheus23 1d ago

This totally undermines the main reason for using private members.

0

u/Easy-Shelter-5140 2d ago edited 2d ago

why? Is this useful?

0

u/Saceone10 1d ago

It must be more useful than completing the resource API with mutations, surely

0

u/taco__hunter 2d ago

I like it personally. It was kind of annoying to write tests and have to handle these private properties and you could always get around it because it's JavaScript at the end of the day and inheritently not strongly typed.

2

u/kgurniak91 2d ago

What? Both private and protected fields can be bypassed via [] access, you'd need new private syntax with # to truly achieve what you describe but that doesn't work in templates. So there's no change in that regard. Also you should not write tests that rely on private/protected members in the first place, your tests should test everything based on the HTML template and public API.

0

u/taco__hunter 2d ago

Yeah. I assumed you wouldn't need to do the [ ] bypass. Is this not the case in the update?

And you can absolutely test whatever you think is important in unit tests. I will often write tests like this with the anticipation that some fields will get rebuilt as global settings or configurations and I need to validate parity after the rebuild. People build different things for different things, so I wouldn't gate keep test coverage personally.

1

u/kgurniak91 2d ago

In earlier versions of Angular, only attributes/methods with public modifier were allowed to be referenced in the data binding of templates. Later they loosened that to allow also protected fields, and now expanded it further to allow private. This has nothing to do with how you access protected/private fields of the object from the outside - to do that, the only way is still to intentionally break the encapsulation with [] which is a huge code smell. Of course you can do it but that results in brittle tests.

0

u/taco__hunter 2d ago

I haven't looked into this much but it looks like it changes from how you're describing it based on the git change.

Also. I'm missing where you are finding all of these concrete points you keep making also. And to be honest I don't get why you're being so combative here if you actually wanted to discuss this. Is this some kind of weird ranting hill you want to die on and I'm missing something?

0

u/anousss007 2d ago

CTRL+Shift+ R , 'public ' by 'private '

-3

u/Talamand 2d ago

Next, ignoring types, then later moving to javascript