0

in my DatePicker <mat-calendar> from Angular Material I want to highlight multiple dates that I read from an HTTP request. I am using Spring Boot as the backend for my application. There I have the entity "Lunch" which has the attribute "LocalDate date"

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
@Table(name = "lunch")
public class Lunch {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @NotNull(message = "date can't be null")
    @Column(columnDefinition = "DATE")
    LocalDate date;
    .
    .
}

I first tried to store the data of this attribute with a GET request in a property in Angular and then read this property in MatCalendarCellCssClasses.

@Component({
  selector: 'app-calendar',
  templateUrl: './calendar.component.html',
  styleUrls: ['./calendar.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class CalendarComponent implements OnInit {

  @Output()
  public changedDateValue = new EventEmitter<Date>();

  public selectedDate: Date = new Date();

  public dates: Date[] = [];

  constructor(private readonly lunchApiService: LunchApiService) { }

  public dateClass() {
    return (date: Date): MatCalendarCellCssClasses => {
      const highlightDate = this.dates
        .some(d => d.getDate() === date.getDate() && d.getMonth() === date.getMonth() && d.getFullYear() === date.getFullYear());
      return highlightDate ? 'special-date' : 'normal-date';
    };
  }

  public onChangedDate(): void {
    this.changedDateValue.emit(this.selectedDate);
  }

  public ngOnInit(): void {
    this.subs.add = this.lunchApiService.findAll().subscribe(
      data => {
      // let x: string[][] = data.map(a => a.date.toString().split(/[x^-]/));
      // let n: number[] = x.map(a => +a[2].replace(/^0+/, ''));
      
        data.forEach(a => this.dates.push(a.date)); // return [ '2022-07-14', '2022-07-15', ... ]
    });
  }
}

<mat-card class="calendar">
  <mat-calendar [(selected)]="selectedDate"
                (selectedChange)="onChangedDate()"
                [dateClass]="dateClass()"></mat-calendar>
</mat-card>

It did not work. What am I doing wrong? How else can I implement my idea?

faxm01
  • 9
  • 3

1 Answers1

0

the problem is that your "dates" is an array of strings (this is good) but you need change the compare with some like

public dateClass() {
    return (date: Date): MatCalendarCellCssClasses => {
      const dateTxt=date.getFullYear()+'-'+
                   ('00'+(date.getMonth()+1)).slice(-2)+"-"+
                   ('00'+date.getDate()).slice(-2))
      return this.dates.find(x=>x==dateTxt)?'special-date' : 'normal-date';
    }
}

NOTE: If your API only get the "special date" from year and month, take a look to this SO -it's a bit old, but I hope already work-

Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Thank u! I had to adjust my property dates: Date[] to dates: string[] and it works, but there is something wrong When starting the application, the dates are not highlighted at first. But when I click the period button (https://i.stack.imgur.com/W3ThQ.png) and click again back, the dates are correctly highlighted! I can't see where my error is! – faxm01 Jul 18 '22 at 14:38
  • The dateClass is executed each time (one for day) the calendar is drawed. be sure that when this happens "this.dates" has values – Eliseo Jul 18 '22 at 16:45
  • I've been trying to fix it but I can't figure it out and I'm desperate as to how to solve it x.x could you please help me? or can you tell me how to proceed? Thankyou! – faxm01 Jul 19 '22 at 19:41