Search code examples
angularangular-materialdialog

Resolving NullInjectorError: No Provider for MatDialogRef in Angular Component


I have created an Angular component that allows creating a task without using a dialog. However, I also want to enable task creation within a dialog.

When I load the website, I encounter a NullInjectorError.

Error:

NullInjectorError: R3InjectorError(Standalone[_App])[MatDialogRef -> MatDialogRef -> MatDialogRef]: NullInjectorError: No provider for MatDialogRef!

I know this error is caused by the following line of code:

private dialogRef: MatDialogRef<TaskFormComponent>

What steps should I take to fix this issue and properly inject MatDialogRef?

Stackblitz

task-form.component.ts

export class TaskFormComponent {
  taskForm!: FormGroup;
  fromPopup = false;

  constructor(
    private dialogRef: MatDialogRef<TaskFormComponent>,
    private taskService: TaskService,
    @Optional()
    @Inject(MAT_DIALOG_DATA)
    public data: { fromPopup: boolean }
  ) {}

  ngOnInit() {
    this.fromPopup = !!this.data?.fromPopup;
    this.taskForm = new FormGroup({
      title: new FormControl(''),
    });
  }

  public onSubmit() {
    if (this.fromPopup) {
      this.dialogRef.close(this.taskForm.getRawValue());
    } else {
      this.taskService.createTask(this.taskForm.getRawValue());
    }
  }
}

main.ts

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [TaskFormComponent],
  template: `
  <app-task-form></app-task-form>
  <br><br><br><br>
  <button (click)="createTask()">Create Task</button>
  `,
})
export class App {
  name = 'Angular';

  constructor(private taskDialogService: TaskDialogService) {}

  public createTask() {
    this.taskDialogService.createTask();
  }
}

task-dialog-service.ts

export class TaskDialogService {
  constructor(private taskService: TaskService, private dialog: MatDialog) {}

  public createTask() {
    this.dialog
      .open(TaskFormComponent, {
        data: { fromPopup: true },
      })
      .afterClosed()
      .pipe(filter((task) => task))
      .subscribe((task) => {
        this.taskService.createTask(task);
      });
  }
}

Solution

  • You should provide them into your standalone task-form.component.ts

    providers: [
        { provide: MatDialogRef,useValue: {} },
        { provide: MAT_DIALOG_DATA,useValue: {} }
    ]