Angular Addicts

Angular Addicts

Share this post

Angular Addicts
Angular Addicts
Master Angular 17.1 and 17.2
User's avatar
Discover more from Angular Addicts
In this publication we collect hand-selected articles & other resources —  e.g. books, talks, podcast episodes — about Angular. Whether you are a professional or a beginner, you’ll find valuable Angular knowledge here.
Over 3,000 subscribers
Already have an account? Sign in

Master Angular 17.1 and 17.2

A study guide that helps you learn what’s new since the 17.0 version of Angular

Gergely Szerovay's avatar
Gergely Szerovay
Feb 27, 2024
7

Share this post

Angular Addicts
Angular Addicts
Master Angular 17.1 and 17.2
Share

Since I published my Master Angular 17 Study guide, the Angular team released two minor versions: Angular 17.1 and 17.2.

This article is also available on dev.to with better source code syntax highlighting.

🎯Changes and new features

In this article, I list out the most important changes and new features, also share resources that will teach you how these new Angular features work:

  • Model signal inputs

  • View queries and component queries as signals

  • ngOptimizedImage: Automatic placeholders

  • ngOptimizedImage: Netlify image loader support

  • Angular CLI: clearScreen option support

  • Angular CLI: define option for declaring global identifiers

This article is also available on dev.to with better source code syntax highlighting.

📌Model signal inputs

PR: Initial implementation of model inputs

Angular 17.2 introduced model inputs. They based on writable signals and defines a input/output pair that can be used in two-way bindings. In the example below, the signals in the two components always have the same value, and you can increase this value by pressing on of the buttons:

@Component({
  selector: 'app-counter',
  standalone: true,
  template: `<button (click)="increase()">Counter's button: {{ value() }}</button>`,
})
export class CounterComponent {
  value = model.required<number>();
  increase() {
    this.value.update((x) => x + 1);
  }
}

@Component({
  selector: 'app-wrapper',
  standalone: true,
  imports: [CounterComponent],
  template: `<app-counter [(value)]="count" />
    <button (click)="increase()">Wrapper's button: {{ count() }}</button>`
})
export class WrapperComponent {
  count = signal(0);
  increase() {
    this.count.update((x) => x + 1);
  }
}

We can also bind an input element's value to a writable signal by two-way data binding, using the 'banana in the box' syntax [(ngModel)]:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    FormsModule,
  ],
  template: `
<textarea
  [(ngModel)]="promptValue"
></textarea>`
})
export class AppComponent {
  promptValue = signal('');
}

Thanks for reading Angular Addicts! Subscribe for free to receive new posts and support my work.

📌View queries and component queries as signals

PR: feat(core): expose queries as signals

With this improvement, we can query elements from the component's template as signals: there are new viewChild(), viewChildren(), contentChild() and contentChildren() functions that return Signals. These are signal based versions of the @viewChild, @viewChildren, @contentChild and @contentChildren decorators:

@Component({
  selector: 'app-vc-query-as-signal',
  standalone: true,
  template: `
    <button (click)="show()">Show</button>
    @if(visible()) {
      <div #id1>Hi!</div>
    }`,
})
class VcQueryAsSignalComponent {
  visible = signal(false);
  divEl = viewChild<ElementRef<HTMLDivElement>>('id1'); // 👈
  effectRef = effect(() => {
    console.log(this.divEl());
  });
  show() {
    this.visible.set(true);
  }
}

// First message on the console: undefined
// The user clicks on the button
// Second message on the console: _ElementRef {nativeElement: div}

📌ngOptimizedImage: Automatic placeholders, Netlify image loader support

Official docs: Automatic placeholders
PR: feat(common): add Netlify image loader
PR: feat(common): add placeholder to NgOptimizedImage

NgOptimizedImage can automatically display a low-res placeholder when using an image CDN.
The Angular team has also added the provideNetlifyLoader preconfigured loader to support the Netlify image CDN.

@Component({
  selector: 'app-image',
  standalone: true,
  imports: [NgOptimizedImage],
  template: `
    <p>Responsive image:</p>
    <!-- 30 x 30 url encoded image as a placeholder 👇 -->
    <img ngSrc="assets/lamp.jpeg" style="max-width: 1024px" [placeholder]="data:@file/jpeg;base64,..." />
  `,
})
export class ImageComponent {
}

// app.config.ts

export const appConfig: ApplicationConfig = {
  // provider for the Netlify image CDN 👇
  providers: [provideNetlifyLoader('https://yoursite.netlify.app/')],
};

📌Angular CLI: clearScreen option support

PR: a957ede build: update angular

Angular can clear the screen before each re-build. You can enable this feature in angular.json, by setting the clearScreen builder option to true (it's false by default):

// angular.json

{
  "projects": {
    "ng172": {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            // 👇 clear the screen before each re-build
            "clearScreen": true,
            // ...            

📌Angular CLI: 'define' option for declaring global identifiers

PR: feat(@angular-devkit/build-angular): add define build option to application builder

The application builder supports the define option for declaring global identifiers. As these identifiers declared in angular.json, not in a .ts support, we can declare it for typescript using a declare const statement in src/types.d.ts. We can use these identifiers as an alternate to the environment files in the future.

@Component({
  template: `
    Text: {{ CONSTANT_IN_ANGULAR_JSON.text }}, 
    Number:{{ CONSTANT_IN_ANGULAR_JSON.number }}`,
})
export class GlobalIdentifierComponent {
  CONSTANT_IN_ANGULAR_JSON = CONSTANT_IN_ANGULAR_JSON;
}

// angular.json

{
  "projects": {
    "ng172": {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            "define": {
              // the value must have a valid JSON syntax 👇
              "CONSTANT_IN_ANGULAR_JSON": "{ 'text': 'This constant is defined in angular.json', 'number': 1 }"
            },
            // ...

// src/types.d.ts

declare const CONSTANT_IN_ANGULAR_JSON: { text: string; number: number };

👨‍💻About the author

My name is Gergely Szerovay, I work as a frontend development chapter lead. Teaching (and learning) Angular is one of my passions. I consume content related to Angular on a daily basis — articles, podcasts, conference talks, you name it.

I created the Angular Addict Newsletter so that I can send you the best resources I come across each month. Whether you are a seasoned Angular Addict or a beginner, I got you covered.

Next to the newsletter, I also have a publication called Angular Addicts. It is a collection of the resources I find most informative and interesting. Let me know if you would like to be included as a writer.

Let’s learn Angular together! Subscribe here 🔥

Follow me on Substack, Medium, Dev.to, Twitter or LinkedIn to learn more about Angular!


Thanks for reading Angular Addicts! Subscribe for free to receive new posts and support my work.

David's avatar
Kevin Agus's avatar
Chris Pinzaru's avatar
7 Likes
7

Share this post

Angular Addicts
Angular Addicts
Master Angular 17.1 and 17.2
Share

Discussion about this post

User's avatar
Unlock the Power of HTTP Request Cancellation in Angular
For faster responses and smoother interactions
May 23, 2023 • 
Gergely Szerovay
3

Share this post

Angular Addicts
Angular Addicts
Unlock the Power of HTTP Request Cancellation in Angular
New Angular 17 feature: new control flow syntax
Angular's new declarative control flow demonstrated by Signal-based examples
Oct 31, 2023 • 
Gergely Szerovay
12

Share this post

Angular Addicts
Angular Addicts
New Angular 17 feature: new control flow syntax
4
New Angular 17 feature: deferred loading
Next level lazy-loading demonstrated by using a Signal-based and other examples
Oct 17, 2023 • 
Gergely Szerovay
8

Share this post

Angular Addicts
Angular Addicts
New Angular 17 feature: deferred loading

Ready for more?

© 2025 Gergely Szerovay
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share

Create your profile

User's avatar

Only paid subscribers can comment on this post

Already a paid subscriber? Sign in

Check your email

For your security, we need to re-authenticate you.

Click the link we sent to , or click here to sign in.