Testing the submission event on a reactive form in Angular

Scenario

In my component, I have a basic form implemented using reactive forms in Angular. My objective is to test the submission event of this form to ensure that the appropriate method is executed.

The Issue at Hand

I am encountering challenges in triggering the submit event of the form.

Code Snippets

Component.html

<form class="form-horizontal"
  id="staticForm"
  [formGroup]="mySimpleForm"
  (ngSubmit)="sendMethod();">
  <input type="text" formGroupName="email">
  <button type="submit">Send form</button>
</form>

Component.ts

  ngOnInit() {
    this.initSimpleForm();
  }

  private initSimpleForm() {
    let file = null;

    this.mySimpleForm = this.formBuilder.group({
      email: [
        '',
        [
          Validators.required
        ]
      ]
    });
  }

  sendMethod() {
    console.log('submitted');
  }

component.spec.ts

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        MyComponent
      ],
      imports: [],
      providers: [
        FormBuilder
      ],
      schemas: [NO_ERRORS_SCHEMA]
    })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    comp = fixture.componentInstance;
});  

it(`should notify in console on form submit`, () => {
    spyOn(console, 'log');

    comp.mySimpleForm.controls['email'].setValue('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b2c6d7c1c6f2c6d7c1c69cd1dddf">[email protected]</a>');
    fixture.debugElement.query(By.css('form')).triggerEventHandler('submit', null);     
    fixture.detectChanges();

    expect(console.log).toHaveBeenCalled(); // FAILS
});

// TO ensure that my spy on console log functions correctly, I performed this test and it passed

it(`will notify on direct sendMethod Call`, () => {
    spyOn(console, 'log');

    comp.sendMethod();      
    fixture.detectChanges();

    expect(console.log).toHaveBeenCalled(); // SUCCESS
});

I have also attempted to trigger the form submission by calling click on the button instead:

fixture.debugElement.query(By.css('button')).triggerEventHandler('click', null);

Is there a workaround to successfully trigger the form submit event?

Answer №1

To start off, you have the first option which involves directly calling the ngSubmit function:

.triggerEventHandler('ngSubmit', null); 

Alternatively, the second option is to import the ReactiveFormsModule, which will automatically set the submit handler on the form. This way, your trigger method should work as expected:

TestBed.configureTestingModule({
      declarations: [
        MyComponent
      ],
      imports: [ReactiveFormsModule], // <== import it
      providers: []

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The distribution of intersection types is not properly handled by Typescript's array.map function

My array is of type object[] & Tree[], but when using arr.map(child => ...), the type of child is inferred as object instead of object & Tree. Is there a way to avoid this without additional casting? It's worth noting that Tree extends ob ...

What is the best way to assign ngModel to dynamically inserted input rows in Angular 4+ (specifically in a mat-table)?

Just a quick question - how can I add ngModel to dynamically added new input rows? I have a Mat table with multiple rows and an "add element" method that adds a new row every time a button is clicked. This way, I want to bind the user-entered values and se ...

What could be causing my view to not update?

Within the code snippet below, I am subscribing to an observable and storing the value of result in the status variable. This variable is then used in an *ngIf statement in the view. However, even when the value is true, the view does not update accordingl ...

Issue with offline functionality in Angular 4 project

I am currently working on an E-commerce Project utilizing Angular 4, Bootstrap, and font-awesome. Additionally, I have incorporated .scss files, angular-cli, and have custom-built a slider component. All libraries, images, and necessary files have been ins ...

Jasmine spying on a standalone function that is not a method of an object

What is the best way to spy on a function that is not a method of an object? In my specific case, the function callMe is not defined on the window object - it is a dependency loaded through angular. if (X) { callMe('hello'); } ...

Transform a literal string type definition into a string value (similar to the typeof operator), or is it the other way around in TypeScript?

Is there a way to retrieve the string value of a string literal type without having to define it twice, similar to the typeof operator in C#? myStringLiteral: 'STRING TYPE'; myString: string = typeof(myStringLiteral); // I want myString to be e ...

Problems with the duration of Shadcn Toasts (Inspired by the react-hot-toast library)

Within a 13.4 Nextjs project (app router), utilizing Typescript and TailwindCSS. I am currently exploring the usage of toasts provided by the remarkable shadcnUI Library, which draws inspiration from react-hot-toast while adding its own unique flair. Imp ...

What steps should be followed to effectively incorporate Google Fonts into a Material UI custom theme for typography in a React/TypeScript project

Hey there, I'm currently working on incorporating Google fonts into a custom Material UI theme as the global font. However, I'm facing an issue where the font-weight setting is not being applied. It seems to only display the normal weight of 400. ...

What steps should I take to resolve the eslint issue indicating that a TypeScript props interface is not being utilized, even though it is being used?

One of my components utilizes AvatarProps for its props: Below is the interface declaration for AvatarProps: export interface AvatarProps { userName: string; userLastName: string; userImg?: string; onPress?: Function; backgroundColorAvatar?: str ...

Issue with Angular2 wysiwyg component failing to submitThe Angular2

I'm currently in the process of familiarizing myself with angular2 by developing a sleek wysiwyg component. However, I seem to have reached an obstacle at this point. Below is the code I've been working on: The form that I am utilizing for testi ...

Instructions on setting a photo as a background image using a text-based model

I'm a beginner with Angular so I may have a simple question. I am using an image from the Google API, which is not a URL. How can I set this image as the background-image in a CSS tag that only accepts URIs? Thank you! ...

Guiding TypeScript to autonomously deduce the precise types of an object that implements a generic interface

Within this code snippet, TypeScript appears to be unaware of the specific type associated with userService.getByUserId in the final line. The expected type should be (userId: string) => ServiceResult<User>, but TypeScript is enforcing a more gene ...

Upon selecting an option in the mat-select element, the form does not update its pristine state to

I recently encountered an issue with my Angular Material mat-select form. I am populating the options from an observable and setting the selected item value programmatically, which is working fine. However, I faced a problem where I expected changing the m ...

In TypeScript, if all the keys in an interface are optional, then not reporting an error when an unexpected field is provided

Why doesn't TypeScript report an error when an unexpected field is provided in an interface where all keys are optional? Here is the code snippet: // This is an interface which all the key is optional interface AxiosRequestConfig { url?: string; m ...

Typescript - Error in Parsing: Expecting an expression

I am currently working with Vue and TypeScript and have encountered a problem. How can I resolve it? Here is the code snippet in question: private setTitle(systemConfig: any) { const systemConfigParse; let obj; systemConfigParse = JSON.parse(sy ...

What is the best RxJS operator to implement additional transformations following mapping?

this.service.retrieveObject(id).map((object)=>{ return transformation1(object); }) .map((object)=>{ return transformation2(object); }); In the following example, the second map call does not have access to the object ...

What steps can I take to avoid the 404 not found error in Angular when I refresh the page?

I am facing a 404 not found error on my Angular project when I upload it to a global server and then refresh the page. How can I resolve this issue? Below is my routing.component.ts file: import { RouterModule, Routes } from '@angular/router'; i ...

What are some ways to utilize tuples in TypeScript along with generics?

My mission is to create a type safe mapping object where I can define key/value pairs just once. I've managed to achieve this with the code below: const myPropTuple = [ [0, "cat"], [1, "dog"], [2, "bird"] ] a ...

Angular 13: SyntaxError Encountered: Token 'export' Not Recognized

After upgrading Angular from version 12 to 13, I encountered an error when running the app: "Uncaught SyntaxError: Unexpected token 'export'." Here are some additional details for context: In the angular.json configuration file, I had specified ...

Implementing pagination within an Angular 11 Mat-table with grouping feature

Encountering an interesting issue with MatTable pagination and grouping simultaneously. I have two components each with a Mat-table featuring Pagination+Grouping. ComponentOne functions smoothly without any issues. When choosing to display 5 elements pe ...