Here is my code :
@Component({
  template: `
    resolveData: {{resolveA}}

    data : {{ dataA }}
  `,
})
class MyComponent {
  @Input() resolveA?: string;
  @Input() dataA?: string;
}

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `

Hello from {{name}}!

    <router-outlet></router-outlet>
  `,
})
export class App {
  name = 'Angular';
}

bootstrapApplication(App, {
  providers: [
    provideRouter(
      [
        {
          path: '**',
          component: MyComponent,
          data: { dataA: 'My static data' },
          resolve: { resolveA: () => 'My resolved data' },
        },
      ],
    ),
  ],
});

MyComponent should display both the static and the resolved data.
Any idea why ?


According to RFC3 signal-based components with change detection strategy based fully on signals are planned as next thing to be released. So as of now, with zone-based change detection strategy, is there any sense of using signals over the traditional way of setting values to class' properties? Will signals' dependency tree eg. gain performance in zone-based components?


I have the following simple code on my component:
import {Component, effect, signal, WritableSignal} from '@angular/core';
import {AppService} from "../app.service";
import {toSignal} from "@angular/core/rxjs-interop";

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {

  translations: WritableSignal<{data: {}}> = signal({data: []});

  constructor( private appService: AppService) {
    this.translations = toSignal(this.appService.getTranslations());
    effect(() => {
      console.log('translation API:', this.translations());
    });
  }

  changeValue(): void {
    this.translations.set({data: {hello: 'hallo'}})

  }
}

FYI: this.appService.getTranslations() returns an observable
I'm trying out the new features released with Angular v16, and how to convert Observables to Signals.
What I wanted to do on the above code is, I change the value of the WritableSignal Object and log its value on change.
I'm getting the following error:
TS2739: Type 'Signal ' is missing the following properties from type 'WritableSignal{ data: {}; }>': set, update, mutate, asReadonly

Help please.


Angular 16 is recently released and I have created a new standalone project without any module.
then in a standalone component I need to import BrowserAnimationsModule from angular/platform-browser/animations. but when I import it, this error occures:

Poviders from the BrowserModule have already been loaded.  If you
need access to common directives such as NgIf and NgFor, import the
CommonModule instead.

and when I remove it this one:

Unexpected synthetic listener @animation.start found. Please make sure
that: Either BrowserAnimationsModule or NoopAnimationsModule are
imported in your application.

so why first error occures? where is BrowserModule already loaded? and if it has already been imported how do I use it?


Before signals, I had an observable that I would watch to trigger a FormControl's editable property, like this:
this.#isItEditor$
    .pipe(takeUntilDestroyed(this.#destroyRef))
    .subscribe(x => {
        const funded = this.formGroup.controls.funded
        if (x)
            funded.enable()
        else
            funded.disable()
    })

Now I've changed from an observable to a signal, but it feels like, in this case, I still need to create an observable from the signal to then do the pipe/subscribe the same way I used to.
I'm not assigning anything based on the signal changing, I'm just implementing a side effect.  Is this correct?


Example from (https://indepth.dev/posts/1518/takeuntildestroy-in-angular-v16)
This works for one subscribe method but doesn't work for two methods
If you look at the following code, then when the component is destroyed, the second subscription will exist. I just can't understand why and how to make the code work for any number of subscriptions in the component? Perhaps I misunderstood something?
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'

  constructor(
  ) {
    interval(1000).pipe(
      takeUntilDestroyed(),
    ).subscribe(console.log)

    interval(1000).pipe(
      takeUntilDestroyed(),
    ).subscribe(console.log)
  }


I am testing angular 16 signals and per my understanding, when I disable zone.js and call signal.update() the view should be updated with new value. It is not. Please help me to understand why.
main.ts
platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: 'noop' })
    .catch(err => console.error(err));

app.component.ts
@Component({
    selector: 'app-root',
    template: '
        <h1>{{ title() }}</h1>
        <button (click)="click()">Change</button>
    ',
})
export class AppComponent {
    title = signal('Hello');

    click(): void {
        this.title.update((value) => value + "!!");
    }
}

I am expecting that after button click, value of 'title' will be updated from 'Hello' to 'Hello!!'. It is not updated.


Code - https://github.com/suyashjawale/Angular16
I have generated my Angular 16 project using following command and selected routing to yes.
ng new myapp --standalone

And then I generated other components using
ng g c components/home

Since, i used --standalone the boilerplate files are different. (Eg. New file app.routes.ts)
 File Structure
Now I want to implement routing So I added the following code to app.routes.ts.
 app.routes.ts
 app.component.html
But the routing doesn't happen. Idk why?. I have restarted the app. still it doesn't work.
So i implemeted loadComponent. But still it doesn't work. Code below.
 loadComponent way.
Am i doing anything wrong. It works with angular 15. But it has app.routing.module.ts. I have restarted the app but still it doesn't work.
FYI - component is standalone

home.component.ts


I am using Angular 16.0.0 and with Angular Universal server side rendering, but when I
Import BrowserModule.withServerTransition in my app module its marked as deprecated, what is the replacement for it ?

my app.module.ts
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {MatMenuModule} from '@angular/material/menu';
import {MatButtonModule} from '@angular/material/button'
import {MatIconModule} from '@angular/material/icon';
import {MatCardModule} from '@angular/material/card';
import { HomeComponent } from './home/home.component';
import {MatTabsModule} from '@angular/material/tabs';
import { CoursesCardListComponent } from './courses-card-list/courses-card-list.component';
import {CourseComponent} from "./course/course.component";
import { MatDatepickerModule } from "@angular/material/datepicker";
import { MatDialogModule } from "@angular/material/dialog";
import { MatInputModule } from "@angular/material/input";
import { MatListModule } from "@angular/material/list";
import { MatPaginatorModule } from "@angular/material/paginator";
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
import { MatSelectModule } from "@angular/material/select";
import { MatSidenavModule } from "@angular/material/sidenav";
import { MatSortModule } from "@angular/material/sort";
import { MatTableModule } from "@angular/material/table";
import { MatToolbarModule } from "@angular/material/toolbar";
import {CoursesService} from "./services/courses.service";
import {CourseResolver} from "./services/course.resolver";
import { CourseDialogComponent } from './course-dialog/course-dialog.component';
import {ReactiveFormsModule} from "@angular/forms";
import { HttpClientModule} from '@angular/common/http';
import {AboutComponent} from './about/about.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    CourseComponent,
    CoursesCardListComponent,
    CourseDialogComponent,
    AboutComponent,

  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    //BrowserTransferStateModule,
    BrowserAnimationsModule,
    MatMenuModule,
    MatButtonModule,
    MatIconModule,
    MatCardModule,
    MatTabsModule,
    MatSidenavModule,
    MatListModule,
    MatToolbarModule,
    MatInputModule,
    MatTableModule,
    MatPaginatorModule,
    MatSortModule,
    MatProgressSpinnerModule,
    MatDialogModule,
    AppRoutingModule,
    MatSelectModule,
    MatDatepickerModule,
    ReactiveFormsModule,
    HttpClientModule
  ],
  providers: [
    CoursesService,
    CourseResolver
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

package.json
{
  "name": "angular-universal-course",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "serve:prerender": "http-server -c-1 dist/angular-universal-course/browser",
    "dev:ssr": "ng run angular-universal-course:serve-ssr",
    "serve:ssr": "node dist/angular-universal-course/server/main.js",
    "build:ssr": "ng build --configuration production && ng run angular-universal-course:server:production",
    "prerender": "ng run angular-universal-course:prerender  --routes routes.txt"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^16.0.0",
    "@angular/cdk": "^16.0.0",
    "@angular/common": "^16.0.0",
    "@angular/compiler": "^16.0.0",
    "@angular/core": "^16.0.0",
    "@angular/forms": "^16.0.0",
    "@angular/material": "^16.0.0",
    "@angular/platform-browser": "^16.0.0",
    "@angular/platform-browser-dynamic": "^16.0.0",
    "@angular/platform-server": "^16.0.0",
    "@angular/router": "^16.0.0",
    "@nguniversal/express-engine": "^16.0.0",
    "@types/express": "^4.17.8",
    "express": "^4.15.2",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.13.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^16.0.0",
    "@angular/cli": "^16.0.0",
    "@angular/compiler-cli": "^16.0.0",
    "@nguniversal/builders": "^16.0.0",
    "@types/jasmine": "~3.8.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^14.15.0",
    "http-server": "^14.0.0",
    "jasmine-core": "~3.8.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~6.3.2",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "ts-node": "~8.3.0",
    "typescript": "~5.0.4"
  }
}


When implementing a ControlValueAccessor I need to dynamically display some content based on whether or not the control is required.  I know I can do this to get the control:
readonly #control = inject(NgControl, {self: true})
protected parentRequires = false

ngOnInit(): void {
  this.#control.valueAccessor = this

  this.parentRequires = this.#control.control?.hasValidator(Validators.required) ?? false
}

but that only checks to see if it's currently required. What I am not seeing though is how to detect changes. The parent is going to toggle the required attribute on/off based on other actions in the application.
I'm looking for something like the non-existent this.#control.control.validatorChanges


I try to get sorted data from MatTableDataSource using this code:
this.source = this.dataSource.sortData(this.dataSource.filteredData,this.dataSource.sort);

but I got this error:

Argument of type 'MatSort | null' is not assignable to parameter of type 'MatSort'.Type 'null' is not assignable to type 'MatSort

I am using Angular 16.


So I just updated my project from Angular v15 to v16, and suddenly I get a lot of missing imports errors thrown, such as  error NG8001: 'mat-icon' is not a known element but I have imported everything accordingly to documentation in my app.module.ts:
import {MatIconModule} from '@angular/material/icon';

@NgModule({
  declarations: [...],
  imports: [..., MatIconModule, ...],
  bootstrap: [AppComponent],
})
export class AppModule {}

Or am I missing something in my package.json? I have tried to update everything according to docs:
 "dependencies": {
   "@angular-devkit/core": "^16.2.0",
   "@angular-devkit/schematics": "^16.2.0",
   "@angular/animations": "~16.2.1",
   "@angular/cdk": "^16.2.1",
   "@angular/common": "~16.2.1",
   "@angular/compiler": "~16.2.1",
   "@angular/core": "~16.2.1",
   "@angular/forms": "~16.2.1",
   "@angular/material": "^16.2.1",
   "@angular/platform-browser": "^16.2.1",
   "@angular/platform-browser-dynamic": "~16.2.1",
   "@angular/router": "~16.2.1",
   "bootstrap": "^4.4.1",
   "moment": "^2.26.0",
   "popper.js": "^1.16.0",
   "rxjs": "^6.5.5",
   "tslib": "^2.0.0",
   "xstate": "~4.6.7",
   "zone.js": "~0.13.1"
 }

I tried deleting node_modules folder and reinstalling, running npm install, and npm ci but nothing has worked till now. I only find the tip to add the missing module to app.module.ts but I have this already, has anyone also run into this problem and found a solution?


I just did import { OrderModule } from 'ngx-order-pipe'; in app.module.ts and added it in imports
  imports: [BrowserModule, OrderModule,...],

and when I did ng serve, I am getting below failed to compile error


Let me preface this question with the fact that I started learning Angular about a month ago.
Basically, I have a searchbar component and several different itemcontainer components (each of them displays a different type of item). In an attempt to have access to the serchbar value on any component, I created a searchbarService like so:
import { Injectable, signal, WritableSignal } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SearchBarService {

  searchTextSignal: WritableSignal<string> = signal('');

  setSearch(text: string): void{
    this.searchTextSignal.set(text);
  }
}

The searchbar component calls the setSearch method on input submit. So far so good. Now, the problem comes when trying to work with searchTextSignal on the itemcontainter components. I'm trying to use it like this:
import { Component, signal} from '@angular/core';
import { Factura } from 'src/app/interfaces/factura';
import { FacturaService } from 'src/app/services/factura.service'; //gets items from a placeholder array.
import { SearchBarService } from 'src/app/services/search-bar.service';

@Component({
  selector: 'vista-facturas',
  templateUrl: './vista-facturas.component.html',
  styleUrls: ['./vista-facturas.component.css']
})
export class VistaFacturasComponent {

    facturasArray: Factura[] = []; // has all items
    filteredFacturasArray = signal<Factura[]>([]); // has all filtered items, and is the value that I want to get updated when the signal changes.

    constructor(private facturaService: FacturaService, public searchBarService: SearchBarService) { }

    getFacturas(): void { //initializes the arrays.
        this.facturaService.getFacturas().subscribe(facturasReturned => this.facturasArray = facturasReturned);
        this.filteredFacturasArray.set(this.facturasArray);
    }

    filterFacturas(): void{ // this method is likely the problem

        let text = this.searchBarService.searchTextSignal();

        if (!text)
            this.filteredFacturasArray.set(this.facturasArray);

        this.filteredFacturasArray.set(this.facturasArray.filter(factura => factura?.numero.toString().includes(text)));
    }

    ngOnInit(): void {
        this.getFacturas();
    }
}

The templace uses ngFor like so:

So, everything boils down to how to make VistaFacturasComponent call filterFacturas() when searchBarService.searchTextSignal() updates. Any ideas?


I have created a custom ui library using only standalone components and here's my public-api.ts file.
/*
 * Public API Surface of ih-ui-lib
 */

export * from './lib/ui-lib.service';
export * from './lib/ui-lib.component';
export * from './lib/ui-lib.module';

// Exporting components
export * from './lib/components/card/card.component';
export * from './lib/components/card/card-heading/card-heading.component';
export * from './lib/components/card/card-content/card-content.component';
export * from './lib/components/cards-responsive/cards-responsive.component';
export * from './lib/components/collapsible/collapsible.component';
export * from './lib/components/heading/heading.component';
export * from './lib/components/icon/icon.component';
export * from './lib/components/paragraph/paragraph.component';
export * from './lib/components/pill/pill.component';
export * from './lib/components/scrollbar/scrollbar.component';
export * from './lib/components/search/search.component';
export * from './lib/components/search/components/search-column/search-column.component';
export * from './lib/components/search/components/search-row/search-row.component';
export * from './lib/components/status-bar/status-bar.component';
export * from './lib/components/timeline/timeline.component';

Here's a example of a component:
import { Component, Input, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'card',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.css']
})
export class CardComponent implements OnInit {

  @Input() classes: string = '';
  @Input() width: string = '';
  @Input() radius: string = 'sm';

  constructor() { }

  ngOnInit(): void {
  }

}

Here's how I'm adding to my app's package.json
  "ui-library": "git+repo+url.git#branch",

I also have index.ts file at the root of my lib which just exports the public-api.ts file so I can access it from the root.
export * from './dist/ih-ui-lib/public-api';
I created a new standalone component in my app and tried to import that component into my app.
And that is when I get this error:
TypeError: Cannot read properties of undefined (reading 'ɵcmp')
I'm using angular 16.
I tried using modules for components and still it is the same.
I tried importing standalone component to a module in my app and it failed to recognise that component.


I've updated my project to Angular 16. In app.module.ts, I have an array of components named entryComponents. However, the entryComponents is no longer available in Angular 16. Where should I add these components to my project:
entryComponents:[
    PayResultDialogComponent,
    MessageBoxComponent
  ],


After Angular CanActivate interface became deprecated, I've changed my guards for simple const functions based on official documentation.
For example here is my inverseAuthGuard method, which seems working correctly:
export const inverseAuthGuard = (): boolean => {
  const authService = inject(AuthService);
  const router = inject(Router);
  if (authService.isAuthenticated()) {
    router.navigate(['/visual-check']);
    return false;
  }
  return true;
};

My problem is that, I want to write some unit tests for it and I don't know how can I inject a mock authService and a mockRouter into this function. I've watched this video, which explains how can I inject mock services into a class, but for my guard function I couldn't make it working.
I have tried some ways, but I couldn' find any solution.
If I do this way:

describe('InverseAuthGuard', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule, RouterTestingModule],
      providers: [
        { provide: AuthService, useValue: AuthService },
        { provide: Router, useValue: Router },
      ],
    });
  });

  fit('should return true on not authenticated user', () => {
    const result = inverseAuthGuard();
    expect(result).toBe(true);
  });
});

I've got the following error:
NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`

If I do that way, what I saw in the video:
describe('InverseAuthGuard', () => {
  const setupWithDI = (authService: unknown, router: unknown) =>
    TestBed.configureTestingModule({
      providers: [
        { provide: AuthService, useValue: authService },
        { provide: Router, useValue: router },
      ],
    }).inject(inverseAuthGuard);

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule, RouterTestingModule],
    });
  });

  fit('should return true on not authenticated user', () => {
    const mockAuthService: unknown = { isAuthenticated: () => true };
    const mockRouter: Router = jasmine.createSpyObj(['navigate']);
    setupWithDI(mockAuthService, mockRouter);
    const result = inverseAuthGuard();
    expect(result).toBe(true);
  });
});

I've got the following error:
NullInjectorError: No provider for inverseAuthGuard!

Of course, I've tried providing inverseAuthGuard somehow, but without any success.
I think there should be an easy solution for it, but I didn't find in any documentation. I will be thanksful for any answer.


My student is asking me : << why should I inject stuff inside the constructor instead of injecting directly in the attribute of the class ?
What I teach to her  :
Use injection inside the constructor
housingLocationList: HousingLocation[] = [];
housingService: HousingService = inject(HousingService);

constructor() {
  this.housingLocationList = this.housingService.getAllHousingLocations();
}

What She wants to do :
Inject the housing service directly inside the class attribute
@Component({
//...
})
export class HomeComponent {

  housingService: HousingService = inject(HousingService);
  housingLocationList: HousingLocation[] = this.housingService.getAllHousingLocations();

  constructor() {}
}

What should I answer to her ?
What I tried :
I tried to convice her that it's a dogma and she should not think about it and just do it like that :)
What I expected :
She accept my answer
What actually resulted:
She still wants to know


I am trying to populate mat-table via dynamic data from an API.
Data is getting populated but pagenation part is unresponsive.
I tried solutions provided in below links on Stackoverflow, non of them worked. I am using Angular 16 and angular material 16.2.10
Solution1
Solution2
Solution3
Solution4
Solution5
PFB my code:
Component.ts:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core';
import {MatPaginator, MatPaginatorModule} from '@angular/material/paginator';
import {MatTableDataSource, MatTableModule} from '@angular/material/table';

@Component({
  selector: 'app-test-api',
  templateUrl: './test-api.component.html',
  styleUrls: ['./test-api.component.css'],
  standalone: true,
  imports: [MatTableModule, MatPaginatorModule]
})
export class TestAPIComponent implements OnInit, AfterViewInit {
  public displayedColumns: string[] = ['id', 'name', 'email', 'city', 'latitude'];
  public getJsonValue: any;
  public dataSource: any = [];
//code for pagination: tried all solutions from stackoverflow , none worked
@ViewChild(MatPaginator) paginator: MatPaginator;
  //@ViewChild(MatPaginator, {read: true}) paginator: MatPaginator;

  /*@ViewChild(MatPaginator, {static: false})
  set paginator(value: MatPaginator) {
    this.dataSource.paginator = value;
  } */

  /*@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
    this.paginator = mp;
    this.dataSource.paginator = this.paginator;
}*/

  constructor(private http : HttpClient){

  }
  ngOnInit(): void {
    this.getMethod();
    //this.cdr.detectChanges();
  }

  public getMethod(){
    this.http.get('https://jsonplaceholder.typicode.com/users').subscribe((data) => {
      console.table(data);
      console.log(this.paginator);
      this.getJsonValue = data;
      this.dataSource = data;
      //tried below code from stackoverflow but didn't work and commented ngAfterViewInit code
      this.dataSource.paginator = this.paginator;
    });

  }

  ngAfterViewInit() {
   //this.dataSource.paginator = this.paginator;
  }
}

HTML:

test-api works!

Test API

Test API: Dynamic

dynamic-table works!

      <ng-container matColumnDef="id">
         Id
         {{element.id}}
      </ng-container>

      <ng-container matColumnDef="name">
         Name
         {{element.name}}
      </ng-container>

      <ng-container matColumnDef="email">
         email
         {{element.email}}
      </ng-container>

      <ng-container matColumnDef="city">
         city
         {{element.address.city}}
      </ng-container>

      <ng-container matColumnDef="latitude">
         Latitude
         {{element.address.geo.lat}}
      </ng-container>

    <mat-paginator [pageSizeOptions]="[5, 10, 20]"
    [pageSize]="5"
                   showFirstLastButtons
                   aria-label="Select page of periodic elements">
    </mat-paginator>

Current Table UI with disabled pagination:


I have this arrangement of the components, such that a component called landing-home.component loads another component client-registration-form.component using ViewContainerRef, on an <ng-template>, rendering on ngAfterViewInit.
The component client-registration-form.component represents a form with input fields. This component has a subject as
messageSource = new BehaviorSubject<ClientRegistrationModel>(new ClientRegistrationModel(..))

which is the form's input data. I want to capture this data in the parent component landing-home.component.
client-registration-form.component.html

        First Name
        <input type="text" [(ngModel)]='clientRegistrationMoel.firstName'/>

        <input type="button" value="Submit" (click)="OnSubmit()">

client-registration-form.component.ts
import { Component, Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import {ClientRegistrationModel} from '../models/client-registration.model';

@Component({
  selector: 'app-client-registration-form',
  templateUrl: './client-registration-form.component.html'
})
@Injectable()
export class ClientRegistrationFormComponent {
   clientRegistrationMoel : ClientRegistrationModel = new ClientRegistrationModel("","","","");
  constructor() {}
  private messageSource = new BehaviorSubject<ClientRegistrationModel>(new ClientRegistrationModel("","","",""));
  public currentMessage = this.messageSource.asObservable();

  OnSubmit()
  {
    this.messageSource.next(this.clientRegistrationMoel);
  }
}

landing-home.component.html

    <ng-template #container></ng-template>

landing-home.component.js
import { Component, ViewChild, ViewContainerRef, Input, ChangeDetectorRef } from '@angular/core';
import {ClientRegistrationFormComponent} from '../client-registration-form/client-registration-form.component';
import {ClientRegistrationModel} from '../models/client-registration.model';

@Component({
  selector: 'app-landing-home',
  templateUrl: './landing-home.component.html'
})

export class LandingHomeComponent {
  @ViewChild('container', {read: ViewContainerRef}) container!: ViewContainerRef;
  constructor(private clientRegistrationFormComponent: ClientRegistrationFormComponent,
              private changeDetector: ChangeDetectorRef){}

  registrationDetails : ClientRegistrationModel = new ClientRegistrationModel('','','','');

  ngAfterViewInit()
  {
    // some condition
    this.container.createComponent(ClientRegistrationFormComponent);
    this.changeDetector.detectChanges();
  }
}

What I am trying to achieve here is that I have a list of child components. Child component A, B, C etc. and a parent component P. The appropriate child will be loaded based on certain condition along with while loading the parent P. Now I want a way to transfer data such as form input (or may be just a boolean flag informing the parent that the form of the child is submitted successfully or failed over a REST call in the child) from the currently loaded child A or B or C.
The above code is just a try to find a way to do this and not necessarily has to follow the same structure but importantly I have a long list of child components and do not want to add those with *ngIf.
Let me know if there is a better approach for such scenario.


I'm migrating from angular 16 to 17 and I encountered the issue that I need to replace all the usages of *ngFor and *ngIf and ngSwitch with the new syntax (@for and @if and @switch).
I know the v17 still supports the old syntax but is there a way to migrate them or a regex to replace them with the new form?


I am unable to add a scrollOffset option to my Angular 17 bootstrap config.
Before Angular 17, you'd have an app module that imports a routing module as such:
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
  },
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      initialNavigation: 'enabledBlocking',
      scrollPositionRestoration: 'enabled',
      anchorScrolling: 'enabled',
      scrollOffset: [0, 100],
      preloadingStrategy: PreloadAllModules,
    }),
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

In Angular 17, you now pass a config object to the bootstrapApplication function, and I am unable to find a way to add the scrollOffset config as before (see above):
// main.ts

import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { withInMemoryScrolling } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(
      routes,
      withInMemoryScrolling({
        scrollPositionRestoration: 'enabled',
        anchorScrolling: 'enabled',
      }),
      // Where can I put my scrollOffset???
    ),
  ],
};


I have an angular project using ng2-right-click-menu for context menu
Since with Angular 16 its not compatible, i have to switch to an alternative solution
When i searched for Angular material menu
<mat-menu>

came across Angular CDK menu.
import {CdkMenuModule} from '@angular/cdk/menu;

Confused which one to use for my application.
As the menu should be customizable.


I’m trying to use the new angular signal effect to listen on changes for a signal array of objects.
But the effect doesn’t get called at any time.
It gets only called if I filter out one object of the array.
Pushing and updating an object of the array doesn’t call the effect.
Here’s my code:
// this code trigger the effect
case "DELETE":
          this.houses.update(((houses: House[]) => houses.filter((house: House) => house.id !== payload.old.id)));
          break;
// this code doesn’t trigger the effect
        case "INSERT":
          this.houses.update((houses: House[]) => {const updatedHouses = houses.push(payload.new); return updatedHouses;})
          break;

effect(() => {
      this.filteredHouses = this.houses();
      this.onFilter();
    });

Obey of I reset the value of the signal and set the new value afterwards, the effect will be called. What am I doing wrong?


Attempting to implement a guard with Okta authentication in Angular v17, I encountered an error indicating a lack of provider for the OktaAuthStateService.
Upon logging in through Okta, I gain access to the login status component. However, when attempting to navigate to the dashboard using routes, I encounter an error related to the absence of a provider, specifically the OktaAuthStateService.
auth.guard.ts
import { Router, UrlTree, } from '@angular/router';
import {  Injectable } from '@angular/core';
import { OktaAuthStateService } from '@okta/okta-angular';
import { Observable, map, take } from 'rxjs';

@Injectable({ providedIn: 'root' }) export class AuthGuard { constructor( public authStateService: OktaAuthStateService, private router: Router ) {}

canActivate(): Observable<boolean | UrlTree> {
return this.authStateService.authState$.pipe( map((loggedIn) => { console.log('loggedIn', loggedIn);
if (!loggedIn) {
      this.router.navigate(['/login']);
      return false;
    }
    return true;
  }),
  take(1)
);
} }

app.module.ts

import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { OktaAuthModule, OKTA_CONFIG } from '@okta/okta-angular';
import { OktaAuth } from '@okta/okta-auth-js';
import myAppConfig from './app.config';
const oktaConfig = myAppConfig.oidc;
const oktaAuth = new OktaAuth(oktaConfig);

@NgModule({
declarations: [],
imports: [OktaAuthModule],
providers: [{ provide: OKTA_CONFIG, useValue: { oktaAuth } }],
bootstrap: [AppComponent],
})
export class AppModule {}

app.routes.ts

import { Routes, mapToCanActivate } from '@angular/router';
import { OktaCallbackComponent, OktaAuthGuard } from '@okta/okta-angular';
import { LoginComponent } from './modules/auth/components/login/login.component';
import { AuthGuard } from './core/guards/auth.guard';
import { DashboardComponent } from './modules/pages/dashboard/dashboard.component';
import { LoginStatusComponent } from './modules/auth/components/login-status/login-status.component';
import { CommonGuard } from './core/guards/common.guard';

export const routes: Routes = [
{
path: '',
redirectTo: 'login',
pathMatch: 'full',
},
{
path: 'login',
component: LoginComponent,
},
{ path: 'login-status', component: LoginStatusComponent },
{ path: 'implicit/callback', component: OktaCallbackComponent },
{
path: 'dashboard',
canActivate: mapToCanActivate([AuthGuard]),
component: DashboardComponent,
},
];


Since angular now has stanalone components, how do we show one comonent inside another like we used to. e.g  inside app body
I dont have any idea about how standalone components work and i'm a fresher in angular just migrated from angular 12 to angular 17.


I am following the docs of angular from Angular Guard
Below is my Guest Guard Code. The logic is to check if the user is available or not,
if available, redirect to dashboard else proceed to login page.
import { CanActivateFn } from '@angular/router';
import { Injectable } from '@angular/core';

@Injectable()

class PermissionsService {
  canActivate(): boolean {
    return false;
  }

}

export const guestGuard: CanActivateFn =  (route, state) => {
  return inject(PermissionsService).canActivate();
};

But this code throws error as
[ERROR] TS2304: Cannot find name 'inject'. [plugin angular-compiler]

src/app/guards/guest.guard.ts:15:13:
  15 │       return inject(PermissionsService).canActivate();


I have been googling this an there are many versions, most are old.
I have an angular 16 project which was not made with standalone components but I've created this 1 standalone component which I want to load as a dialog.
My question is, in angular 16, how do I go about loading a standalone component without the use of routing or preloading it?
Can it be done?
Any guidance would be appreciated as there's just too many versions on the internet.


Angular is failing to compile because of the following error and I'm really confused as to why.
error TS2322: Type 'string' is not assignable to type 'MenuItem'.

4     <menu-item item={{item}}></menu-item>
                 ~~~~

  apps/angular-monorepo/src/app/app.component.ts:10:16
    10   templateUrl: './app.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component AppComponent.

Why is it complaining that item is of type 'string' when I specified that item is of type MenuItem or undefined
@Component({
  standalone: true,
  imports: [NxWelcomeComponent, RouterModule, MenuItemComponent],
  selector: 'angular-monorepo-root',
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent {
  title = 'angular-monorepo';
  menu: MenuItem[] = [
    {id: 101,category: 'appetizer', name:'french toast', price: 10.00},
    {id: 201,category: 'entree',sub_category:"rice",name:'pork', price: 10.00},
    {id: 301,category: 'drinks',name:'tea', price: 10.00},
    {id: 401,category: 'dessert',name:'affogato', price: 10.00},
  ]
}
//app.component.html
<router-outlet></router-outlet>

POS

@for (item of menu; track item.id) {
    <menu-item item={{item}}></menu-item>
}

@Component({
  selector: 'menu-item',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './menu-item.component.html',
  styleUrl: './menu-item.component.scss',
})
export class MenuItemComponent {
  constructor() {

  }
  @Input({required: true}) item: MenuItem | undefined = undefined;

  @Output() itemSelectedEvent = new EventEmitter<number>();
}

//menu-item.component.html
@if (item) {

{{item.name}}

}

//menu-item.type.ts
export type MenuItem = {
    id: number,
    category: ItemCategory,
    sub_category?: string,
    name: string,
    price: number
  }

I expect item would be of type MenuItem like I specified


Example:
https://stackblitz.com/edit/myxj6y?file=src%2Fexample%2Fsnack-bar-overview-example.ts
I tried the class in styles.scss, with ng-deep, overriding the component's root class and it still doesn't work. I'm not using standalone components. What is wrong with the code ?
"@angular/material": "^16.2.9",
"@angular/common": "^16.2.0",


I have updated my Angular app to version 16 and now in older browsers I am getting the error which says "SyntaxError: private fields are not currently supported."
I am trying to use polyfills to support modern browser features in the older browsers.
Here is the polyfills.ts file:
import 'core-js';
import 'core-js/stable';
import 'regenerator-runtime/runtime';

import 'zone.js';

This is the tsconfig.json
"compilerOptions": {
    "target": "es2015"
  },

This is the error on Firefox (v75):


after migrating to new angular 17 and updating my template, ng serve throws this message
NG5002: Cannot parse expression. @for loop expression must match the pattern " of
"


I'm using Angular material's AutoComplete as follows
    <form class="form">
        <mat-form-field class="search-user">
            <mat-label>User</mat-label>
            <input type="text" matInput [formControl]="userCtrl" [matAutocomplete]="auto">
            <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
                @if(userCtrl.value?.length < 3) {

Type 3 or more characters

                } @else if(isLoading) {

loading...

                } @else if (!(filteredOptions | async)?.length) {

No match found

                }
                @for (option of filteredOptions | async; track option) {
                    <mat-option [value]="option">{{option}}</mat-option>
                    }
            </mat-autocomplete>
        </mat-form-field>
    </form>

This is more or less a copy-past from one of their examples.
But what I would like to add is text above the options (inside the overlay) if there are no options (yet)
@if(userCtrl.value?.length < 3) {

Type 3 or more characters

} @else if(isLoading) {

loading...

} @else if (!(filteredOptions | async)?.length) {

No match found

}

However, the overlay is closed when there are 0 options. Is there a way, such that I can show/activate the overlay when the input has focus and 0 options (empty array)? But when the user select an options, the focus is lost and the overlay closes
DEMO


I'm developing a solution Angular 16 Material using the free theme Matero.
I started from the downloadable demo so Angular Core ^16.2.7 etc.(https://github.com/ng-matero/ng-matero/blob/main/package.json), deleting the unuseful demo parts.
I'm facing a problem with subscribing after a http call, i need to declare
@Component({
  ...
  changeDetection: ChangeDetectionStrategy.OnPush,
})

in the constructor
export class LoginComponent {
  isSubmitting = false;
  ...
  constructor(
    ...
    private ref: ChangeDetectorRef,
  ) {}

and finally after a call for example a login
    this.isSubmitting = true;
    this.auth
      .login(this.username.value, this.password.value, this.rememberMe.value)
      .pipe(filter(authenticated => authenticated))
      .subscribe({
        next: () => {
            this.isSubmitting = false;
            this.ref.markForCheck();
        },

in the html for example a button
<button class="w-full m-y-16" mat-raised-button color="primary"
        [loading]="isSubmitting"
        (click)="login()">{{'login' | translate}}</button>

With the previous code, pratically it should happens nothing (there is no router redirection) but by clicking the button the spinner inside the button should cease to spin and appear back the "Login" text.
But this happens because the "this.ref.markForCheck();" otherwise without this call it ignores the change of isSubmitting and the spinner remain here.
The same for an http call ( normal call with HttpClient that returns an Observable) with binding to a mtx-grid, the binding succeed only by calling "this.ref.markForCheck();" in the "subscribe".
Angular CLI is 16.2.10
What i'm doing in a wrong manner ?


The first step
    ng add @angular-eslint/schematics

executes successfully but the second step
    ng g @angular-eslint/schematics:convert-tslint-to-eslint

produces this error:
    Error: The `convert-tslint-to-eslint` schematic is no longer supported.

    Please see https://github.com/angular-eslint/angular-eslint/blob/main/docs/MIGRATING_FROM_TSLINT.md

and the readme document referenced in the error message is the one I was following to attempt this migration.
I successfully used this schematic about about three weeks ago.
Has anyone else encountered this error message? Know of a workaround?
Angular CLI: 17.0.7
Node: 18.13.0
Package Manager: npm 8.19.3
OS: darwin x64

Angular: 17.0.7
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1700.7
@angular-devkit/build-angular   17.0.7
@angular-devkit/core            17.0.7
@angular-devkit/schematics      17.0.7
@schematics/angular             17.0.7
rxjs                            7.8.1
typescript                      5.2.2
zone.js                         0.14.2


I have an Angular 17 application which uses standalone components, the initial routes are set up like so in app.routes.ts
export const appRoutes: Array<Route> = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  {
    path: 'login',
    component: LoginComponent,
    title: 'Login',
  },
  {
    path: '',
    canActivateChild: [AuthGuard],
    loadChildren: () => import(`./app-authorized.routes`).then((r) => r.appAuthorizedRoutes),
  },
  { path: '**', redirectTo: '/dashboard' },
];

Once the user logs in they are authorized and redirected to /dashboard, and the app-authorized.routes.ts routes are loaded. Here is what that file looks like:
export const appAuthorizedRoutes: Array<Route> = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard],
    title: 'Dashboard',
  },
  {
    path: 'settings',
    component: SettingsComponent,
    canActivate: [AuthGuard],
    title: 'Settings',
  },
  //etc...
];

An issue I have is that after logging in, there is a delay as the data loads and the UI looks strange.  I have a navigation bar set to appear when authorized, which shows but the login component is also still showing - which is wrong.
After logging in and while the lazy-loaded chunks are loading, is there a way to display this progress in the UI somehow?


I have an Angular 17 application using standalone components, the initial routes are set up like so in app.routes.ts
export const appRoutes: Array<Route> = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  {
    path: 'login',
    component: LoginComponent,
    title: 'Login',
  },
  {
    path: '',
    canActivateChild: [AuthGuard],
    loadChildren: () => import(`./app-authorized.routes`).then((r) => r.appAuthorizedRoutes),
  },
  { path: '**', redirectTo: '/dashboard' },
];

Once the user logs in they are authorized and redirected to /dashboard, and the app-authorized.routes.ts routes are loaded. Here is what that file looks like:
export const appAuthorizedRoutes: Array<Route> = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard],
    title: 'Dashboard',
  },
  {
    path: 'settings',
    component: SettingsComponent,
    canActivate: [AuthGuard],
    title: 'Settings',
  },
  //etc...
];

I have several services that can only be used once the user logs in, but currently upon inspecting the chunked files Angular loads, all of the services are loaded initially at the login page.  Of course this makes sense because they are decorated with
@Injectable({
  providedIn: 'root',
})

Modules of course would make this easy, but since I'm not using modules how do I tell my application to include only certain services along with the lazy-loaded routes, or just any way after the user logs in?


I am migrating old angular project to latest angular 17. I changed class based auth guard to functional auth guard. The problem I am having is that I get this error:
ERROR NullInjectorError: NullInjectorError: No provider for _UserService!
at NullInjector.get (core.mjs:5626:27)
at R3Injector.get (core.mjs:6069:33)
at R3Injector.get (core.mjs:6069:33)
at injectInjectorOnly (core.mjs:911:40)
at ɵɵinject (core.mjs:917:42)
at inject (core.mjs:1001:12)
at authGuard (auth.guard.ts:6:23)
at router.mjs:3323:134
at runInInjectionContext (core.mjs:6366:16)
at router.mjs:3323:89

Here is my authGuard code:
import {CanActivateFn, Router} from '@angular/router';
import {inject} from "@angular/core";
import {UserService} from "../users/user.service";

export const authGuard: CanActivateFn = (route, state) => {
  const userService = inject(UserService);
  const router = inject(Router);

  if (!userService.is_authenticated()) {
    router.navigate(['login', state.url]);
    return false;
  }
  return true;
};

Here is part of my UserService:
import {Injectable} from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
import {HttpClient} from '@angular/common/http';

@Injectable()
export class UserService {
    private usersUrl = '/users/';

    constructor(private http: HttpClient,
                private jwtHelper: JwtHelperService) { }

    ...

    public is_authenticated(): boolean {
        const token = localStorage.getItem('token');
        // Check whether the token is expired and return
        // true or false
        return !this.jwtHelper.isTokenExpired(token);
    }
}

As I understand the documentation I don't need to provide UserService anywhere. Using 'inject' should be enough. What am I doing wrong?


I apologize in advance if i am asking too stupid questions but i am really new to angular and i do not understand how to handle a JSON object coming from the server and convert that object into a custom datatype so i can use that data to render on html using ngFor.
I have tried multiple things but nothing seems to work. Any help will be very much appreciated.
P.S. please excuse me for the extremely simple html page, application is coming up from scratch and i am working on functionalities and backend server connections before working on the designs.
Below is the Code and screenshots attached.
Employee.Component.html

Inside Employee Component.

<button type="submit" class="btn btn-login float-center" (click)="getAllEmployees1()">getAllEmployees</button>

Employee List

     {{ employees }}

employee.component.ts file

employees: any;

 constructor(private service: EmployeeServiceService){
  }
  ngOnInit(){

  }

  public getAllEmployees1(){
    this.service.getAllEmployees().subscribe((data)=>{

      this.employees = data;
      console.log("Response: "+ this.employees);
    },
    (error) =>{
      console.error('Error fetching employees: ', error);
    }
    );
  }

EmployeeService file:

@Injectable({
  providedIn: 'root'
})
export class EmployeeServiceService {

  constructor(private http:HttpClient) { }

  getAllEmployees(){
    console.log("Inside get ALL Employees Method.");
    return this.http.get("https://localhost:9090/employee/getAllEmployees",{responseType:'text' as 'json'});
  }

Employee class type:

export class AddEmployee{
    firstName: any;
    lastName: any;
    address:any;
    project:any
    ssn:any;
    joinDate:any;
    status:any

        constructor(
            firstName: string,
            lastName: string,
            address:string,
            project:string,
            ssn:number,
            joinDate:Date,
            status:number
        ){}
    }

I wanted to convert the JSON data coming from the server to AddEmployee type and then run a ngFor loop in the html so i can put everything in the tabular format.
But angular keeps on complaining that the data i am getting is in Object Format and ngFor can only be used on observables and iterators. Below is the image attached of how the object gets pulled from server and when i click on getAllEmployees button, it just renders the object itself. I am not able to print the data if i dont call {{ employees }} directly.
enter image description here
Error Page:


I want to create a dynamic form that is an array of payments, the user can add a new payment, delete from the array, and edit.
My HTML:
<form [formGroup]="createLoanPaymentsForm" (ngSubmit)="createLoan()">
    <ng-container formArrayName="createLoanPaymentsForm">
        @for (
            createLoanPaymentForm of createLoanPaymentsForm.controls; // here is the error
            track $index
        ) {
            <div [formGroup]="createLoanPaymentForm">
                <mat-form-field appearance="fill">
                    <input matInput formControlName="title" placeholder="Lesson title" />
                </mat-form-field>
            </div>
        }
        <button mat-mini-fab (click)="addPayment()">Add</button>
    </ng-container>
</form>

The configuration of my component:
@Component({
    selector: 'app-create-loan-dialog',
    standalone: true,
    imports: [
        MatInputModule,
        MatButtonModule,
        MatDialogTitle,
        MatDialogContent,
        MatDialogActions,
        MatDialogClose,
        ReactiveFormsModule,
        MatStepperModule,
    ],
    providers: [
        {
            provide: STEPPER_GLOBAL_OPTIONS,
            useValue: { showError: true },
        },
    ],
    templateUrl: './create-loan-dialog.component.html',
})

My FormGroup:
createLoanPaymentsForm: FormGroup = this.formBuilder.group({
    payments: this.formBuilder.array([]),
});

There is an error in my loop, it says:

Type '{ [key: string]: AbstractControl<any, any>; }' must have a 'Symbol.iterator' method that returns an iterator.

The solution for this bug, possible the correct configuration for a FormArray loop in Angular 17


I recently Upgraded to Angular to V17 with SSR and when i tried to load page this error is coming. ERROR Error: NullInjectorError: No provider for SocialAuthServiceConfig!
Note: - I am using Only standalone components (No modules)
Need help to resolve this issue
ERROR Error: NullInjectorError: No provider for SocialAuthServiceConfig!
    at t (angular/node_modules/zone.js/fesm2015/zone-error.js:85:33)
    at NullInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:5626:27)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)
    at injectInjectorOnly (angular/node_modules/@angular/core/fesm2022/core.mjs:911:40)
    at Module.ɵɵinject (angular/node_modules/@angular/core/fesm2022/core.mjs:917:42)
    at initialState (angular/node_modules/@abacritt/angularx-social-login/fesm2022/abacritt-angularx-social-login.mjs:374:46)
    at eval (angular/node_modules/@angular/core/fesm2022/core.mjs:6189:43)
    at runInInjectorProfilerContext (angular/node_modules/@angular/core/fesm2022/core.mjs:867:9)
    at R3Injector.hydrate (angular/node_modules/@angular/core/fesm2022/core.mjs:6188:17)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6058:33)
    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)
    at ChainedInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:15378:36)
    at lookupTokenUsingModuleInjector (angular/node_modules/@angular/core/fesm2022/core.mjs:4137:39)
    at getOrCreateInjectable (angular/node_modules/@angular/core/fesm2022/core.mjs:4185:12) {
  originalStack: 'Error: NullInjectorError: No provider for SocialAuthServiceConfig!\n' +
    '    at t (angular/node_modules/zone.js/fesm2015/zone-error.js:85:33)\n' +
    '    at NullInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:5626:27)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at injectInjectorOnly (angular/node_modules/@angular/core/fesm2022/core.mjs:911:40)\n' +
    '    at Module.ɵɵinject (angular/node_modules/@angular/core/fesm2022/core.mjs:917:42)\n' +
    '    at initialState (angular/node_modules/@abacritt/angularx-social-login/fesm2022/abacritt-angularx-social-login.mjs:374:46)\n' +
    '    at eval (angular/node_modules/@angular/core/fesm2022/core.mjs:6189:43)\n' +
    '    at runInInjectorProfilerContext (angular/node_modules/@angular/core/fesm2022/core.mjs:867:9)\n' +
    '    at R3Injector.hydrate (angular/node_modules/@angular/core/fesm2022/core.mjs:6188:17)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6058:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at ChainedInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:15378:36)\n' +
    '    at lookupTokenUsingModuleInjector (angular/node_modules/@angular/core/fesm2022/core.mjs:4137:39)\n' +
    '    at getOrCreateInjectable (angular/node_modules/@angular/core/fesm2022/core.mjs:4185:12)',
  zoneAwareStack: 'Error: NullInjectorError: No provider for SocialAuthServiceConfig!\n' +
    '    at t (angular/node_modules/zone.js/fesm2015/zone-error.js:85:33)\n' +
    '    at NullInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:5626:27)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at injectInjectorOnly (angular/node_modules/@angular/core/fesm2022/core.mjs:911:40)\n' +
    '    at Module.ɵɵinject (angular/node_modules/@angular/core/fesm2022/core.mjs:917:42)\n' +
    '    at initialState (angular/node_modules/@abacritt/angularx-social-login/fesm2022/abacritt-angularx-social-login.mjs:374:46)\n' +
    '    at eval (angular/node_modules/@angular/core/fesm2022/core.mjs:6189:43)\n' +
    '    at runInInjectorProfilerContext (angular/node_modules/@angular/core/fesm2022/core.mjs:867:9)\n' +
    '    at R3Injector.hydrate (angular/node_modules/@angular/core/fesm2022/core.mjs:6188:17)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6058:33)\n' +
    '    at R3Injector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:6069:33)\n' +
    '    at ChainedInjector.get (angular/node_modules/@angular/core/fesm2022/core.mjs:15378:36)\n' +
    '    at lookupTokenUsingModuleInjector (angular/node_modules/@angular/core/fesm2022/core.mjs:4137:39)\n' +
    '    at getOrCreateInjectable (angular/node_modules/@angular/core/fesm2022/core.mjs:4185:12)',
  ngTempTokenPath: null,
  ngTokenPath: [
    '_SocialAuthService',
    '_SocialAuthService',
    'SocialAuthServiceConfig',
    'SocialAuthServiceConfig'
  ]
}


I am learning Angular multiple content projection from new Angular 17 docs.
When I am using example from doc I am getting error:
profile.component.html::

  <ng-content select="profile-header"></ng-content>

  <ng-content></ng-content>

  <ng-content select="profile-footer"></ng-content>

In app.component.html::
<app-profile>
    <profile-header>
Header 1
</profile-header>

This is projected content

</app-profile>

I am getting this error::
NG8001: 'profile-header' is not a known element:

How can I resolve it?


Following is my Standalone api calls containing  service:

import { Injectable} from '@angular/core';
import { ProductEndPoints } from '../../constants/apiConstants/product-endpoints';
import { HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment.development';
import { product } from '../../models/product.types';
@Injectable({
  providedIn: 'root',
})
export class ProductService {

  constructor(private http:HttpClient) { }

  getAllProducts():Observable<product[]>{
     return this.http.get<product[]>(environment.apiUrl+`${ProductEndPoints.getAllProduct}`)
  }

  getProductDetailById(id:string):Observable<product>{
    return this.http.get<product>(environment.apiUrl+`${ProductEndPoints}/${id}`)
  }
}

I also added this service to target component's providers array.
The error I got while injecting it to the standalone component is :
src_app_pages_Product_product-routing_ts.js:2 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(Standalone[ProductListComponent])[HttpClient -> HttpClient -> HttpClient -> HttpClient]:
  NullInjectorError: No provider for HttpClient!
NullInjectorError: R3InjectorError(Standalone[ProductListComponent])[HttpClient -> HttpClient -> HttpClient -> HttpClient]:
  NullInjectorError: No provider for HttpClient!
    at NullInjector.get (core.mjs:8890:27)
    at R3Injector.get (core.mjs:9334:33)
    at R3Injector.get (core.mjs:9334:33)
    at R3Injector.get (core.mjs:9334:33)
    at R3Injector.get (core.mjs:9334:33)
    at ChainedInjector.get (core.mjs:14018:36)
    at lookupTokenUsingModuleInjector (core.mjs:4608:39)
    at getOrCreateInjectable (core.mjs:4656:12)
    at ɵɵdirectiveInject (core.mjs:11801:19)
    at Module.ɵɵinject (core.mjs:848:60)
    at resolvePromise (zone.js:1193:31)
    at resolvePromise (zone.js:1147:17)
    at zone.js:1260:17
    at _ZoneDelegate.invokeTask (zone.js:402:31)
    at core.mjs:10757:55
    at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:10757:36)
    at _ZoneDelegate.invokeTask (zone.js:401:60)
    at Object.onInvokeTask (core.mjs:11070:33)
    at _ZoneDelegate.invokeTask (zone.js:401:60)
    at Zone.runTask (zone.js:173:47)


I'm quite new to Angular.
I have this HTML file new-team.component.html:
<app-header></app-header>

          New team creation

          <form #formNewTeam="ngForm" (ngSubmit)="onSubmitNewTeam(formNewTeam)">

              Team Name
              <input type="text" class="form-control" id="teamName" placeholder="Team name" ngModel #teamName="ngModel"
                name="teamName" required minlength="6" pattern="^[a-zA-Z0-9À-ú.-]{6,}">

Team Name is required

                  Your team name must be at least 6 characters long and without special characters except -

              <ng-select [items]="countries" bindLabel="frenchName" bindValue="id" placeholder="Select a country for your team">
                <ng-template ng-label-tmp let-item="item">
                  {{item.frenchName}}
                </ng-template>
                <ng-template ng-option-tmp let-item="item" let-index="index">

                  {{item.frenchName}}
                </ng-template>
              </ng-select>

            <button type="submit" class="btn btn-primary">Create</button>
          </form>

and this is my component file:
import { Component, OnDestroy, OnInit } from '@angular/core';
import { NgForm } from "@angular/forms";
import { Subscription } from "rxjs";
import { Country } from 'src/app/_models/country.model';
import { CountryService } from 'src/app/_services/country.service';
import { User } from "../../_models/user.model";
import { AuthService } from "../../_services/auth.service";

@Component({
  selector: 'app-new-team',
  templateUrl: './new-team.component.html',
  styleUrls: ['./new-team.component.scss']
})
export class NewTeamComponent implements OnInit, OnDestroy {
  user!: User;
  countries: Country[] = [];
  AuthUserSub!: Subscription;

  constructor(
    private authService: AuthService,
    private countryService: CountryService
  ) {
  }
  ngOnInit(): void {

    this.AuthUserSub = this.authService.AuthenticatedUser$.subscribe({
      next: user => {
        if (user) this.user = user;
      }
    })

    this.countryService.getAllCountries().subscribe({
      next: data => {
        this.countries = data;
        this.countries.forEach(element => {
          element.logo = "/assets/flags/" + element.logo;
        });
      },
      error: err => console.log(err)
    })
  }

  onSubmitNewTeam(formNewTeam: NgForm) {
    console.log(formNewTeam);
    if (!formNewTeam.valid) {
      return;
    }
  }

  ngOnDestroy() {
    this.AuthUserSub.unsubscribe();
  }
}

On the line where I call the console.log(formNewTeam); on my .ts file I just have the value of the input field, not the value selected into the <ng-select>.
How can I send these two values (input field + value of the <ng-select>) to my backend API?
By the way, the Country object contains id, frenchName, and logo.
I should receive the form with these two values for example: teamName = "Real Madrid" and countryId = "10"
Thank you in advance.


I am trying to work with AWS in angular but at the very start after I install AWS-SDK:
npm install aws-sdk

After adding the below to my file-manager.ts, I am getting errors regarding node and stream.
import * as aws from 'aws-sdk';

I added the following as suggested buy the compiler:
Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.

and still getting so many errors.


I am trying to build Angular 17 application with SSR, using built in i18n mechanism. And I don't get how to configure it to work together.
v17 is brand new and there are blank spaces in documentation and not a lot of examples over the Internet.
When creating simple application with Angular+SSR it creates server.ts alongside base application
// imports

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();
  const serverDistFolder = dirname(fileURLToPath(import.meta.url));
  const browserDistFolder = resolve(serverDistFolder, '../browser');
  const indexHtml = join(serverDistFolder, 'index.server.html');

  const commonEngine = new CommonEngine();

  server.set('view engine', 'html');
  server.set('views', browserDistFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(browserDistFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Angular engine
  server.get('*', (req, res, next) => {
    const { protocol, originalUrl, baseUrl, headers } = req;

    commonEngine
      .render({
        bootstrap,
        documentFilePath: indexHtml,
        url: `${protocol}://${headers.host}${originalUrl}`,
        publicPath: browserDistFolder,
        providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
      })
      .then((html) => res.send(html))
      .catch((err) => next(err));
  });

  return server;
}

function run(): void {
  const port = process.env['PORT'] || 4000;

  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

run();

and after building the app it creates the following structure in dist folder:
# simple-ssr

* [browser/](./simple-ssr/browser)
  * [first/](./simple-ssr/browser/first)
    * [index.html](./simple-ssr/browser/first/index.html)
  * [home/](./simple-ssr/browser/home)
    * [index.html](./simple-ssr/browser/home/index.html)
  * [second/](./simple-ssr/browser/second)
    * [index.html](./simple-ssr/browser/second/index.html)
  * [favicon.ico](./simple-ssr/browser/favicon.ico)
  * [index.html](./simple-ssr/browser/index.html)
  * [main-OUKHBY7S.js](./simple-ssr/browser/main-OUKHBY7S.js)
  * [polyfills-LZBJRJJE.js](./simple-ssr/browser/polyfills-LZBJRJJE.js)
  * [styles-Y4IFJ72L.css](./simple-ssr/browser/styles-Y4IFJ72L.css)
* [server/](./simple-ssr/server)
  * [chunk-53JWIC36.mjs](./simple-ssr/server/chunk-53JWIC36.mjs)
  * ... other chunks
  * [index.server.html](./simple-ssr/server/index.server.html)
  * [main.server.mjs](./simple-ssr/server/main.server.mjs)
  * [polyfills.server.mjs](./simple-ssr/server/polyfills.server.mjs)
  * [render-utils.server.mjs](./simple-ssr/server/render-utils.server.mjs)
  * [server.mjs](./simple-ssr/server/server.mjs)
* [3rdpartylicenses.txt](./simple-ssr/3rdpartylicenses.txt)
* [prerendered-routes.json](./simple-ssr/prerendered-routes.json)

running node dist/simple-ssr/server/server.mjs starts the Express server and everything works fine.
The problem starts after adding Angular built-in i18n.
Afer seetting up everything and localizing the app it works okay with ng serve.
But building dist version it generates another nested structure:
# simple-ssr-with-i18n

* [browser/](./my-app/browser)
  * [en-US/](./my-app/browser/en-US)
    * [assets/](./my-app/browser/en-US/assets)
      * [img/](./my-app/browser/en-US/assets/img)
    * [first/](./my-app/browser/en-US/first)
      * [index.html](./my-app/browser/en-US/first/index.html)
    * [home/](./my-app/browser/en-US/home)
      * [index.html](./my-app/browser/en-US/home/index.html)
    * [second/](./my-app/browser/en-US/second)
      * [index.html](./my-app/browser/en-US/second/index.html)
    * [favicon.ico](./my-app/browser/en-US/favicon.ico)
    * [index.html](./my-app/browser/en-US/index.html)
    * [main-VKL3SVOT.js](./my-app/browser/en-US/main-VKL3SVOT.js)
    * [polyfills-LQWQKVKW.js](./my-app/browser/en-US/polyfills-LQWQKVKW.js)
    * [styles-UTKJIBJ7.css](./my-app/browser/en-US/styles-UTKJIBJ7.css)
  * [uk/](./my-app/browser/uk)
    * [assets/](./my-app/browser/uk/assets)
      * [img/](./my-app/browser/uk/assets/img)
    * [first/](./my-app/browser/uk/first)
      * [index.html](./my-app/browser/uk/first/index.html)
    * [home/](./my-app/browser/uk/home)
      * [index.html](./my-app/browser/uk/home/index.html)
    * [second/](./my-app/browser/uk/second)
      * [index.html](./my-app/browser/uk/second/index.html)
    * [favicon.ico](./my-app/browser/uk/favicon.ico)
    * [index.html](./my-app/browser/uk/index.html)
    * [main-VKL3SVOT.js](./my-app/browser/uk/main-VKL3SVOT.js)
    * [polyfills-LQWQKVKW.js](./my-app/browser/uk/polyfills-LQWQKVKW.js)
    * [styles-UTKJIBJ7.css](./my-app/browser/uk/styles-UTKJIBJ7.css)
* [server/](./my-app/server)
  * [en-US/](./my-app/server/en-US)
    * [index.server.html](./my-app/server/en-US/index.server.html)
    * [main.server.mjs](./my-app/server/en-US/main.server.mjs)
    * [polyfills.server.mjs](./my-app/server/en-US/polyfills.server.mjs)
    * [render-utils.server.mjs](./my-app/server/en-US/render-utils.server.mjs)
    * [server.mjs](./my-app/server/en-US/server.mjs)
  * [uk/](./my-app/server/uk)
    * [index.server.html](./my-app/server/uk/index.server.html)
    * [main.server.mjs](./my-app/server/uk/main.server.mjs)
    * [polyfills.server.mjs](./my-app/server/uk/polyfills.server.mjs)
    * [render-utils.server.mjs](./my-app/server/uk/render-utils.server.mjs)
    * [server.mjs](./my-app/server/uk/server.mjs)
* [3rdpartylicenses.txt](./my-app/3rdpartylicenses.txt)
* [prerendered-routes.json](./my-app/prerendered-routes.json)

folder structure for i18n & ssr
Obviously pathes in server.ts and, as a result, in dist/simple-ssr-with-i18n/server/en-US/server.mjs are not set up right for working correctly with different locale versions.
And as I imagined it should work simply with following changes
  const languageFolder = basename(serverDistFolder);
  const languagePath = `/${languageFolder}/`;
  const browserDistFolder = resolve(
    serverDistFolder,
    '../../browser' + languagePath
  );

and running separate express server instance for each locale. (Ideally one server serving all locales, of course)
But all of my attempts were not successful, running node dist/simple-ssr/server/server.mjs leads to unresponsive site with errors fetching static .js file chunks.
May somebody provide some comprehensive example for server.ts and setting up i18n+ssr together?
Only relible article I found is Angular-universal-and-i18n-working-together
but it's outdated, and i get built-time errors on baseHref step.
P.S. Chatgpt is aware of Angular 15 and Universal, so it's not also very helpfull.


We are trying to implement deferrable views for a component in angular. This component is present in a component which is used by a parent in another repo. While defer seems to be working when we implemented it inside component of the same project, its not working when imported and used in a library. Two issue here actually:

code is not split into a new bundle but loaded along with the main library bundle
placeholder element appears for a split second and then the view disappears. on checking the html i found that I cannot see the child elements of the deferred component, its just like a dummy element

Here are the things which I have followed as a requirement:

Using angular 17 in both the main project and library project
Using on viewport condition to defer the block
the component inside the defer block is a standalone component
component is not used anywhere outside the defer block and also not referenced using viewchild

Is there anything I'm doing wrong or any additional requirement I need to follow ?


I have this

     {{ dt }}

and I want to refactor to angular v17 syntax
@for (dt of totals; track $index) {
    {{ dt }}
}

How do I refactor the [ngClass] on the
?
I tried this but obviously It doesn't work because the variable dt is not yet defined inthe

    @for (dt of totals; track $index) {
        {{ dt }}
    }

I could try this but I don't want an extra ng-container on every element:

    @for (dt of totals; track $index) {
        <ng-container [ngClass]="{ up: dt.isUp }">
            {{ dt }}
        </ng-container>
    }

What's the official way to do this?
edit:
Thanks for the help, I got the resolution I needed. The question is silly because I forgot that the *ngFor repeats the element it is in and its children. I forgot that and thought it was only repeating its children. That is basic pre-v17 angular. I'll leave this question in case this catches anyone else.


Hi i'm new to angular 17, i'm following the course tour of heroes on the website.
After creating the project, i create a new component heroes just like the tutorial tells me to.
I add the component selector to app.component.html like this :
<app-heroes></app-heroes>
As i am trying to serve the project i have this error :
[ERROR] NG8001: 'app-heroes' is not a known element:

If 'app-heroes' is an Angular component, then verify that it is included in the '@Component.imports' of this component.

If 'app-heroes' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@Component.schemas' of this component to suppress this message. [plugin angular-compiler]
src/app/app.component.html:0:0:
0 │
╵ ^

Error occurs in the template of component AppComponent.
src/app/app.component.ts:9:15:
  9 │   templateUrl: './app.component.html',

Can someone help please ??
I tried to do ng serve --open and want it to serve in my browser but it's not working.


My Application has some generic pages like the landing or logout page which are navigatable when the user is not logged in. Those shall be rendered normally within the primary router-outlet.
Then I have Pages that are for logged-in users as the core of the application state and those pages shall be rendered within a general layout component that contains the navigation, footer, header etc.
I am having trouble to render those children within a named router-outlet that I expect to be within my layout component.
app.routes.ts
export const routes: Routes = [
{ path: '', redirectTo: 'landing', pathMatch: 'full' },
{
    path: 'landing',
    component: LandingPageComponent
},
{
    path: 'intern',
    component: NavigationComponent,
    children: [
        {
            path: 'enterprise',
            component: OverviewComponent,
        },
        { path: '', redirectTo: 'enterprise', pathMatch: 'full' },
    ]
},

];
navigation.component.html

<router-outlet name="intern"></router-outlet>

Landing and Navigation component are rendered as expected, but the content of the pages that I want to be within the navigation component in the named router-outled "intern" are not there. Sidenote: As I understood - as long as the child route and the named router-outlet share the same name (here 'intern'), i do not need to define the "outled: 'intern'" property in the app.routes.ts


I want to implement AuthGuard using CanActivateFn in Angular 16 which should prevent to view some pages for unauthorized users.
isUserLoggedIn method in UserService is a get request to the backend which returns a loggedin user or throws UNAUTHORIZED exception.
I want to call isUserLoggedIn in AuthGuard and check if it throws UNAUTHORIZED exception then redirect to "/unauth" path otherwise it should return true and do nothing.
The problem: isUserLoggedIn returns Observable<AuthorizedUser> and CanActivateFn needs type boolean. Is there any way to do this without changing the actual GET request in backend ?
@Injectable({providedIn: 'root'})
export class UserService {

 isUserLoggedIn(): Observable<AuthorizedUser> {
   const headers = new HttpHeaders({'Content-Type': 'application/json'});
   return this.apiHandlerService.get<AuthorizedUser>(API_URL, headers);
 }
}

import {CanActivateFn, Router,} from '@angular/router';
import {inject} from '@angular/core';
import {catchError, map, of} from "rxjs";

export const AuthGuard: CanActivateFn = (route, state) => {
    const authService: UserService = inject(UserService);
    const router: Router = inject(Router);

    return authService.isUserLoggedIn().pipe(
        map(response => {
            console.log('Response ', response);
            return true;
        }),
        catchError(error => {
            router.navigate(['/unauthorized'])
            return of(false);
        })
    )
}


I am running Angular 17 projects with standalone components.
I want to add a service where i will start and stop the ngx-ui-loader (
https://www.npmjs.com/package/ngx-ui-loader).
I can't do normal module where i will provide in root ngxui loader like in older versions, so i am wondering if this can work in Angular17?
When loader is directly called and imported in a standalone component it works.
Current implementation is not working..
Service code:
import { Injectable, inject } from '@angular/core';
import { NgxUiLoaderService } from 'ngx-ui-loader';

@Injectable({
  providedIn: 'root',
})
export class LoaderService {
//   ngxLoader = inject(NgxUiLoaderService);
  ngxLoader = inject(NgxUiLoaderService);

  startLoader() {
    console.error('start');
    console.error(this.ngxLoader);
    this.ngxLoader.start();
  }

  stopLoader() {
    this.ngxLoader.stop();
  }

  loaderConfig =
  {
    "bgsColor": "red",
    "bgsOpacity": 0.5,
    "bgsPosition": "bottom-right",
    "bgsSize": 60,
    "bgsType": "ball-spin-clockwise",
    "blur": 5,
    "delay": 0,
    "fastFadeOut": true,
    "fgsColor": "red",
    "fgsPosition": "center-center",
    "fgsSize": 60,
    "fgsType": "ball-spin-clockwise",
    "gap": 24,
    "logoPosition": "center-center",
    "logoSize": 120,
    "logoUrl": "",
    "masterLoaderId": "master",
    "overlayBorderRadius": "0",
    "overlayColor": "rgba(40, 40, 40, 0.8)",
    "pbColor": "red",
    "pbDirection": "ltr",
    "pbThickness": 3,
    "hasProgressBar": true,
    "text": "",
    "textColor": "#FFFFFF",
    "textPosition": "center-center",
    "maxTime": -1,
    "minTime": 300
  }
}

AppComponent.ts

`import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NavbarComponent } from './components/navbar/navbar.component';
import { NgxUiLoaderModule, NgxUiLoaderService } from 'ngx-ui-loader';
import { LoginComponent } from './components/login/login.component';
import { UserService } from './services/user.service';
import { StorageService } from './services/storage.service';
import { finalize, first } from 'rxjs';
import { LoaderService } from './services/loader.service';

@Component({
  selector: 'app-root',
  standalone: true,
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
  imports: [CommonModule, NavbarComponent, NgxUiLoaderModule, LoginComponent],
})
export class AppComponent {
  title = 'CinAppClient';
  userService = inject(UserService);
  storageService = inject(StorageService);
  ngxLoaderService = inject(NgxUiLoaderService);
  loaderService = inject(LoaderService);

  user$ = this.userService.user$;
  constructor() {}

  ngOnInit() {
    this.loaderService.startLoader();
    let storageUser = this.storageService.getUser();
    if (storageUser !== null) {
      this.userService.authToken = storageUser.token;
      this.userService
        .refreshToken()
        .pipe(
          first(),
          finalize(() => this.loaderService.stopLoader())
        )
        .subscribe();
    }
  }
}
type here

appComponent.html
<ngx-ui-loader [bgsType]="'three-strings'" [fgsType]="'three-strings'">
</ngx-ui-loader>`
type here


Angular v17 onwards defaults to the Standalone approach in the CLI, and there's no more explicit use of @NgModule for application organization. My question is regarding lazy loading with the new default configuration.
Suppose I define my routes in the following way (as im using standalone components):
export const routes: Routes = [
    {'path' : '', component: DashboardComponent},
    {'path' : 'users', component: UsersComponent},
    {'path' : '**', component: DashboardComponent},
];

Will lazy loading still work with this new standalone-oriented approach, or is it necessary to adhere to the traditional @NgModule and feature module way to apply the lazy loading concept in Angular v17? I'd appreciate any insights, experiences, or documentation references related to this potential change in behavior.


I have this code
this.items.mutate(products => this.sourceData.getData().forEach(item => products.push(item)));

updating the library from Angular 16 to Angular 17 I need to remove 'mutate' using 'update' or 'set', but I don't know how to do it.
I should change products.push(item)-> [...products, item] but I don't know how to do it with the forEach.


I am encountering an issue with my Angular 17 SSR (Server-Side Rendering) application. I am using ApexCharts/ng-apexcharts, which currently only works on the browser side. The specific error message I'm facing is:

I understand that this error is expected in an SSR environment, and disabling SSR resolves the issue. However, I am looking for a more robust solution. After some research, I came across the afterNextRender() function, which seems promising.
I am seeking guidance on how to implement afterNextRender() to handle this situation in an Angular 17 SSR application. I believe this could be a valuable workaround, but I'm struggling with the implementation.
Any help or suggestions would be greatly appreciated. Thank you in advance for your assistance!
ps : the chart is displayed but ReferenceError: window is not defined in the terminal is annoying it occurs everytime i import ApexCharts
Here's my current code snippet:
my dashboard.component.ts :
import { AfterRenderPhase, Component, ElementRef, OnInit, ViewChild, afterNextRender } from '@angular/core';
import ApexCharts from 'apexcharts';
import {
  ApexAxisChartSeries,
  ApexChart,
  ApexDataLabels,
  ApexLegend,
  ApexStroke,
  ApexTitleSubtitle,
  ApexXAxis,
  ApexYAxis,
} from 'ng-apexcharts';
export type ChartOptions = {
  series: ApexAxisChartSeries;
  chart: ApexChart;
  xaxis: ApexXAxis;
  stroke: ApexStroke;
  dataLabels: ApexDataLabels;
  yaxis: ApexYAxis;
  title: ApexTitleSubtitle;
  labels: string[];
  legend: ApexLegend;
  subtitle: ApexTitleSubtitle;
};
export const series = {
  // dummy data from apex docs
};
@Component({
  selector: 'app-dashboard',
  standalone: true,
  imports: [],
  templateUrl: './dashboard.component.html',
  styleUrl: './dashboard.component.scss'
})
export class DashboardComponent implements OnInit {
  @ViewChild('chart') chart!: ElementRef;
  public chartOptions!: Partial<ChartOptions>;

  constructor() {
    // im struggling here
    afterNextRender(() => {
      const element = this.chart.nativeElement;
      var chart = new ApexCharts(element, this.chartOptions);
      chart.render()
    }, {phase: AfterRenderPhase.Read});
  }

  ngOnInit(): void {
    this.chartOptions = {
      series: [
        {
          name: 'STOCK ABC',
          data: series.monthDataSeries1.prices,
        },
      ],
      // chart options config from apex docs
    };
  }
}

in my dashboard.component.html
<div #chart  id="chart"> </div>


Issue
I'm working with an Angular v17 app configured in standalone mode, experiencing issues integrating with Keycloak libraries. Specifically, Keycloak isn't automatically appending the authorization header to backend requests. For security reasons, I prefer not to manually handle the Authorization Token.

I installed Keycloak libs "npm install keycloak-angular"
I added a provider for the Keycloak init
I added some test code to signin and execute a request

All this code is working well with Angular non standalone (NgModule). But since I switched to standalone in angular 17, something is fishy.
To test my code, I have configured an Interceptor: authInterceptorProvider. That is adding the Token manually to each request. Works well. But I don't want to handle tokens by hand...
What might I be missing or configuring wrong?
Code bits (image upload is not working at the moment)
Here my simplyfied Application config
  export const initializeKeycloak = (keycloak: KeycloakService) => {
return () =>
  keycloak.init({
    config: {
      url: 'http://localhost:8180/',
      realm: 'balbliblub-realm',
      clientId: 'blabliblubi-public-client',
    },
    initOptions: {
      pkceMethod: 'S256',
      redirectUri: 'http://localhost:4200/dashboard',
    },
    loadUserProfileAtStartUp: false
  });}

export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes),
  provideHttpClient(
    withFetch(),
    withXsrfConfiguration(
    {
      cookieName: 'XSRF-TOKEN',
      headerName: 'X-XSRF-TOKEN',
    })
  ),

  authInterceptorProvider,
  importProvidersFrom(HttpClientModule, KeycloakBearerInterceptor),
  {
    provide: APP_INITIALIZER,
    useFactory: initializeKeycloak,
    multi: true,
    deps: [KeycloakService],
  },
  KeycloakService,
]};

Here my AppComponent
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent implements OnInit {
  title = 'testy';
  public isLoggedIn = false;
  public userProfile: KeycloakProfile | null = null;

  constructor(private readonly keycloak: KeycloakService,
              private http: HttpClient) { }

  public async ngOnInit() {
    this.isLoggedIn = await this.keycloak.isLoggedIn();

    if (this.isLoggedIn) {
      this.userProfile = await this.keycloak.loadUserProfile();
    }
  }

  login() {
    this.keycloak.login();
  }

  protected loadAbos() {
    this.http.get<Abo[]>('http://localhost:8080/api/abos?email=' + this.userProfile?.email, { observe: 'response',withCredentials: true })
      .pipe(
        catchError(err => this.handleError("Could not load abos", err)),
        /// if no error occurs we receive the abos
        tap(abos => {
          console.info("loaded abos", abos);
        })
      ).subscribe()
  }

Thanks 4 your help <3


Working with Angular15.
Create a lazy loading modules
app-routing.module.ts
    const routes: Routes = [
      { path: '', redirectTo: '/dashboard', patchMatch: 'full' },
      { path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule) },
      { path: 'module1', loadChildren: () => import('./module1/module1.module').then(m => m.FirstModule) },
      { path: 'module2', loadChildren: () => import('./module2/module2.module').then(m => m.SecondModule) },
      { path: 'module3', loadChildren: () => import('./module3/module3.module').then(m => m.ThirdModule) },
      { path: 'module4', loadChildren: () => import('./module4/module4.module').then(m => m.FourthModule) },
    ];

@NgModule({
imports: [RouterModule.forChild(routes, {useHash:true})]
exports: [RouterModule]
})
export class AppRoutingModule {}

dashboard.module.ts -- Having components dependency with FirstModule, SecondModule, ThirdModule and FourthModule
const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent},
];

@NgModule({
declarations: [DashboardComponent, DashboardDetailsComponent]
imports: [RouterModule.forChild(routes), FirstModule, SecondModule, ThirdModule, FourthModule]
exports: [RouterModule],
bootstrap: [DashboardComponent]
})
export class DashboardModule {}

module1.module.ts  -- Having components dependency with SecondModule and ThirdModule
const routes: Routes = [
  { path: 'module1', component: Module1Component},
  { path: 'module1/details', component: Module1DetailsComponent},
];

@NgModule({
declarations: [Module1Component, Module1DetailsComponent]
imports: [RouterModule.forChild(routes), SecondModule, ThirdModule]
exports: [RouterModule],
bootstrap: [Module1Component]
})
export class FirstModule {}

module2.module.ts  -- Having components dependency with ThirdModule
const routes: Routes = [
  { path: 'module2', component: Module2Component},
  { path: 'module2/details', component: Module2DetailsComponent},
];

@NgModule({
declarations: [Module2Component, Module2DetailsComponent]
imports: [RouterModule.forChild(routes), ThirdModule]
exports: [RouterModule],
bootstrap: [Module2Component]
})
export class SecondModule {}

With the above code getting error
Error: NG04007: The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector. Lazy load modules hould use RouterModule.forChild instead
Its working fine only if DashboardModule is explicitly imported in AppRoutingModule


I have an Angular service that successfully stores the key and value but fails to retrieve it.  Below is the code:
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})

export class StorageService {
  constructor() {}

  // Store the value - (Note: This code works fine.  The key is userData and it stores an array of user credentials as value )

  async store(storageKey: string, value: any) {
    localStorage.setItem('key', storageKey);
    localStorage.setItem('value', value);
  }

  // Get the value - Here I provide the userData as key but I get a null value.  If put key in "key" then I get an error.  I have verified with console.log(key) that accurate key is passed to retrieve the value.

  async get(key: string) {
    const ret = localStorage.getItem(key);
    return JSON.parse(ret);
  }
}


I updated my projecto Angular 17.1 and now when i try ng build it creates a server.mjs file in /dist//server directory which is meant to be served for production. when I try to run the file with node or pm2 i get the following error
TypeError: Nl is not a function
    at $C (file:///Users/goldenfox/Projects/front/dist/karlancer/server/server.mjs:106:5771)
    at GC (file:///Users/goldenfox/Projects/front/dist/karlancer/server/server.mjs:106:6227)
    at file:///Users/goldenfox/Projects/front/dist/karlancer/server/server.mjs:106:6318
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.11.0

Any Idea about how I can fix this ?


I want to display items of an array of strings from index 1.
arr = [ "str1", "str2", "str3", "str4", "str5" ]

Output should be:
str2
str3
str4
str5

Print all except first one, using new @for loop in angular.


In my Statistics module I got a signal that defines the type of the charts that should appear and this signal is updated using a radio button group.
The signal: typeSignal = signal<string>('OIA')
The radio buttons that sets the :

     @for (type of types; track $index) {
            <input type="radio" class="btn-check" name="btnradio" [id]="type" autocomplete="off"
                [checked]="type==typeSignal()">
            {{type}}
     }

However, I got another computed signal that creates the charts data according to the type signal. Here's the charts signal:
  charts = computed(() => {
    const chartsArr:ChartData[] = []
   if (this.typeSignal() == "OIA") {

      chartsArr.push(this.createBarChart("Status of Incident", ['Closed', 'Ongoing'], "status", "Advisories", true))
      chartsArr.push(this.createBarChart("Severity of Incident", ['Severity 0', 'Severity 1', 'Severity 2', 'Severity 3', 'Severity 4'], "impacts", "Advisories", false))
      chartsArr.push(this.createDonutChart("Communication type", ['Incident', 'Change'], 300))

    } else if (this.typeSignal() == "Portail de l'information") {

      chartsArr.push(this.createBarChart("Status of Incident", ['Scheduled', 'Archived', 'Ongoing'], "status", "Advisories", true))
      chartsArr.push(this.createBarChart("Impact of Incident", ['Major', 'Minor', 'Grave'], "impacts", "Advisories", false))
      chartsArr.push(this.createDonutChart("Communication type", ['Incident', 'Change'], 300))

    } else if (this.typeSignal() == "Bulletin Board") {
      chartsArr.push(this.createBarChart("Status of Change", ['Closed', 'Ongoing', 'Scheduled'], "status", "Advisories", true))
      chartsArr.push(this.createBarChart("Outage of Incident", ['Complete Outage', 'Partial Outage', 'Info'], "impacts", "Advisories", false))
      chartsArr.push(this.createDonutChart("Communication type", ['Info', 'Incident', 'Change'], 300))
    }
    console.log(chartsArr);
    return structuredClone(chartsArr)
  })

and I read this charts signal in my template
@if (["OIA","Portail de l'information","Bulletin Board"].includes(typeSignal())) {

    @for (chart of charts(); track $index) {
    @if (chart.type == "bar") {
    <app-bar-chart [title]="chart.title" [axissLabels]="chart.labels" [values]="chart.values"
        [valuesType]="chart.valuesType!" [isHorizontal]="chart.isHorizontal!"></app-bar-chart>
    }@else if (chart.type=="donut") {
    <app-donut-chart [title]="chart.title" [values]="chart.values" [labels]="chart.labels"
        [minWidth]="chart.minWidth!"></app-donut-chart>
    }
    }

}

The problem here is that the charts signal doesn't update the for loop although the console.log(chartsArr); inside it gets logged whenever I toggle the radio buttons.


I'm trying to create a dynamic form array in Angular 17 with a child component handling part of the input. However, I'm encountering an error:

Type 'AbstractControl<any, any>' is missing the following properties from type 'FormGroup': controls, registerControl, addControl, removeControl, and 2 more.

Here's my code:
Parent component:
@Component({
  selector: 'app',
  template: `
  <form [formGroup]="categoryForm" (ngSubmit)="onSubmit()">

        <ng-container [formGroupName]="i">

          <app-category [formGroup]="category" [categories]="categories"  [index]="i"></app-category>

        </ng-container>

    <button class="btn" type="button" (click)="addCategory()">Add Category</button>
    <button class="btn" type="submit">Submit</button>
  </form>

{{this.categoryForm.value | json}}
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [ReactiveFormsModule, JsonPipe, NgFor, CategoryComponent],
})
export class AppComponent {
  categoryForm!: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    this.categoryForm = this.fb.group({
      categories: this.fb.array([]),
    });
  }

  get categories(): FormArray {
    return this.categoryForm.get('categories') as FormArray;
  }

  addCategory() {
    this.categories.push(
      this.fb.group({
        categoryID: '',
        categoryName: '',
        sections: this.fb.array([]),
      })
    );
  }

  removeCategory(catIndex: number) {
    this.categories.removeAt(catIndex);
  }

  onSubmit() {
    console.log(this.categoryForm.value);
  }
}

Child component:
@Component({
  selector: 'app-category',
  template: `
  <form [formGroup]="formGroup">

Category : {{index+1}}

      Category ID :
      <input type="text" formControlName="categoryID" />
      Category Name:
      <input type="text" formControlName="categoryName" />

      <button type="button" class="remove" (click)="removeCategory()">Remove Category</button>

  </form>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [ReactiveFormsModule, NgFor],
})
export class CategoryComponent {
  @Input() categories!: FormArray;
  @Input() formGroup!: FormGroup;
  @Input() index!: number;

  removeCategory() {
    this.categories.removeAt(this.index);
  }
}

I've created a form array in the parent component and tried to loop through it using *ngFor, passing each form group to the child component. The child component receives the form group via @Input() and handles part of the input fields.
Can someone help me understand why this error is occurring and how to resolve it? Thank you!


I migrated to angular 17.1. When I ran the app, I noticed error information about using fetch with httpClient for SSR.
NG02801: Angular detected that `HttpClient` is not configured to use `fetch` APIs. It's strongly recommended to enable `fetch` for applications that use Server-Side Rendering for better performance and compatibility. To enable `fetch`, add the `withFetch()` to the `provideHttpClient()` call at the root of the application.

Application is not bootstrap by standalone component but I found only tutorials for that kind of apps. I put provideHttpClient(withFetch()), to app.server.module.ts and error disappeared.
Im not sure if it is a correct solution for application bootstraped by AppModule. Do you have better options?


I have this new angular signal variables on my component:
private employees: Signal<Employee[]> = this.employeesService.filteredEmployeesSignal;
public employeesDataSource = computed(
    () => new MatTableDataSource<Employee>(this.employees())
);

All works fine until tests fails with this error:
this.employees is not a function
when tries to access to this.employees() signal value. It detects as a function instead as a signal value getter.
I tried to get the value in other local constant inside the computed signal but the error persist.


As you know in angular 17 we can have different syntax for ngIf, ngFor and so on. Am looking for an efficient way of migrating old syntax in html files to the new on presented in Angular 17:
For example I had this old html in angular 15:
<ng-container *ngIf="!dynamicWidth; else FlexibleRef">

</ng-container>

<ng-template #FlexibleRef>

</ng-template>

And need it in the new syntax like this:
@if (!dynamicWidth) {

} @else {
    @for (item of count | numberRange; track item; let i = $index) {

.

   }
}


How can I define the index variable in @for in Angular 17
const users = [
    { id: 1, name: 'Ali' },
    { id: 2, name: 'reza' },
    { id: 3, name: 'jack' },
  ];

  @for (user of users; track user.id; let i = index) {

{{ user.name + i }}

  } @empty {
  Empty list of users
  }

index is not known as we had in *ngFor and got Unknown "let" parameter variable "index" in Angular17 @for
But the following is working:

{{ user.name + i }}