Hamza Haddad
Hamza Haddad

Reputation: 1556

Set component providers depending on @input

I would use material datepicker with selection strategy

Sometimes I should not use the selection strategy.

But like it is instanciated in the providers array . I can't find a way to set it or not conditionally.

import { Component, Injectable, Input } from '@angular/core';
import { DateAdapter } from '@angular/material/core';
import {
  MatDateRangeSelectionStrategy,
  DateRange,
  MAT_DATE_RANGE_SELECTION_STRATEGY,
} from '@angular/material/datepicker';

@Injectable()
export class FiveDayRangeSelectionStrategy<D>
  implements MatDateRangeSelectionStrategy<D>
{
  constructor(private _dateAdapter: DateAdapter<D>) {}

  selectionFinished(date: D | null): DateRange<D> {
    return this._createFiveDayRange(date);
  }

  createPreview(activeDate: D | null): DateRange<D> {
    return this._createFiveDayRange(activeDate);
  }

  private _createFiveDayRange(date: D | null): DateRange<D> {
    if (date) {
      const start = this._dateAdapter.addCalendarDays(date, -2);
      const end = this._dateAdapter.addCalendarDays(date, 2);
      return new DateRange<D>(start, end);
    }

    return new DateRange<D>(null, null);
  }
}

/** @title Date range picker with custom a selection strategy */
@Component({
  selector: 'app-date-range-picker-selection-strategy',
  templateUrl: 'date-range-picker-selection-strategy-example.html',
  providers: [
    {
      provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
      useClass: FiveDayRangeSelectionStrategy,
    },
  ],
})
export class DateRangePickerSelectionStrategyExample {
  @Input() set selectionStrategy(value:boolean) {
    if(value) {
      //// Sould provide selection strategy
    }
    else {
     //// sould not
    }
  };
}

app.component.html

<p><b>Sould use selection strategy</b></p>
<app-date-range-picker-selection-strategy [selectionStrategy]="true"></app-date-range-picker-selection-strategy>
<mat-divider></mat-divider>
<p><b>Sould <span [ngStyle]="{'color':'red'}">not</span> use selection strategy</b></p>
<app-date-range-picker-selection-strategy [selectionStrategy]="false"></app-date-range-picker-selection-strategy>

Actually I'm creating two date-picker components : one with selection Strategy and one without.

I would like to know how can I use only one component for the two use cases ?

I have read a lot about useValue/useFactory/useClass but I didn't get to the solution.

Stackblitz

Upvotes: 1

Views: 1041

Answers (1)

yurzui
yurzui

Reputation: 214017

You can try using useFactory option like:

@Component({
  selector: 'app-date-range-picker-selection-strategy',
  templateUrl: 'date-range-picker-selection-strategy-example.html',
  providers: [
    {
      provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
      useFactory: (
        comp: DateRangePickerSelectionStrategyExample,
        adapter: DateAdapter<unknown> 
      ) => {
        return comp.selectionStrategy
          ? new FiveDayRangeSelectionStrategy(adapter)
          : null;
      },
      deps: [DateRangePickerSelectionStrategyExample, DateAdapter],
    },
  ],
})
export class DateRangePickerSelectionStrategyExample {
  @Input() selectionStrategy!: boolean;
}

Forked Stackblitz

Upvotes: 5

Related Questions