Angular 14 standalone component with animations and Jasmin test

This issue has been tracked since 2022-09-07.

Which @angular/* package(s) are the source of the bug?

animations, platform-browser-dynamic

Is this a regression?

No

Description

I have created animated, standalone component like this:

import { animate, state, style, transition, trigger } from '@angular/animations';
import { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { faChevronDown, faChevronUp, IconDefinition } from '@fortawesome/free-solid-svg-icons';

import { ButtonColor } from '../button/button.component';

@Component({
  selector: 'uic-expandable-section',
  imports: [FontAwesomeModule, BrowserAnimationsModule],
  templateUrl: './expandable-section.component.html',
  styleUrls: ['./expandable-section.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  animations: [
    trigger('openClose', [
      state(
        'open',
        style({
          height: '*',
          overflow: 'hidden',
          borderWidth: '1px',
        })
      ),
      state(
        'closed',
        style({
          height: '0',
          overflow: 'hidden',
          borderWidth: '0',
        })
      ),
      transition('open => closed', [animate('500ms ease-in')]),
      transition('closed => open', [animate('500ms ease-out')]),
    ]),
  ],
})
export class ExpandableSectionComponent {
  @Input() public toggleButtonColor: ButtonColor;
  @Input() public toggleButtonLabel: string;

  @HostBinding('class') public get hostClass(): Array<string> {
    return ['class.uic-expandable-section'];
  }

  public isOpen = false;

  public get toggleButtonIcon(): IconDefinition {
    return this.isOpen ? faChevronUp : faChevronDown;
  }

  public toggleExpandableSectionState(): void {
    this.isOpen = !this.isOpen;
  }
}

And here is my test for the component:

import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ExpandableSectionComponent } from './expandable-section.component';

describe('ExpandableSectionComponent', () => {
  let fixture: ComponentFixture<ExpandableSectionComponent>;
  let component: ExpandableSectionComponent;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      imports: [FontAwesomeModule, NoopAnimationsModule, ExpandableSectionComponent],
    })

      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(ExpandableSectionComponent);
        component = fixture.componentInstance;
      });
  }));

  it('should create', () => {
    expect(component).toBeDefined();
  });
});

When I run my test I get an Error:

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

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

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

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 14.2.1
Node: 16.13.1
Package Manager: npm 8.3.1 
OS: win32 x64

Angular: 14.2.0
... animations, common, compiler, compiler-cli, core, elements
... forms, platform-browser, platform-browser-dynamic, router

Anything else?

No response

AndrewKushnir wrote this answer on 2022-09-08

@p-rogulski you can use provideAnimations and provideNoopAnimations functions (and use the results in the providers array) instead of importing animation-related modules:

This should bring the necessary providers without bringing the BrowserModule, which would help avoid the issue.

p-rogulski wrote this answer on 2022-09-08

@AndrewKushnir But what if this component is a part of standalone components library?

If I understand corectly the provider can be use only in:

bootstrapApplication(RootComponent, { providers: [ provideAnimations() ] });

when the RootComponent exists?
In my case I have just one standalone component - main.ts file does not exists.

AndrewKushnir wrote this answer on 2022-09-08

You can also use the provideAnimations or provideNoopAnimations in the TestBed like this:

    TestBed.configureTestingModule({
      imports: [FontAwesomeModule, ExpandableSectionComponent],
      providers: [provideNoopAnimations()]
    });
More Details About Repo
Owner Name angular
Repo Name angular
Full Name angular/angular
Language TypeScript
Created Date 2014-09-18
Updated Date 2022-09-30
Star Count 84091
Watcher Count 3064
Fork Count 22233
Issue Count 1203

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date