Search code examples
angulardate-fns

Number of weeks are not getting the right value of date in Angular app


I'm making a planner project, and I use datefns library. I have a function the gives the number of weeks in a year. The problem is as soon as I click the selected week (dropdown) it doesn't give the right date. I want to display the first and the last day of the selected week. For now I can only display the first day. How to display the correct date of the selected week and last day of the selected week?

Here is my ts code:

export class AppComponent implements OnInit {
  selectedWeek! : Date;
  weeks!: any[];
  display = false;
  date =  new Date(); //null

 constructor() {}

  ngOnInit(): void {
    this.selectedWeek = new Date();
    this.weeks = this.getWeeks();
  }
  getWeeks() {
    const startDate = new Date(new Date().getFullYear(), 0, 1); // first day of the year
    console.log(startDate);

    const endDate = new Date(new Date().getFullYear(), 11, 31); // last day of the year
    console.log(endDate);

    // How many full weeks are between end date & start date
    var result = [];
    const count = differenceInWeeks(endDate, startDate);
    result = Array.from({ length: count }, (_, i) => `Week ${i + 1}`);

    console.log('array of weeks', count);
    return result;
  }

  changeWeek(week: Date) {
    let date = week;
    this.selectedWeek = date;
    this.weeks = this.getWeeks();
    this.display = true;
  }
}

And my template code

<h2 style="margin: 10px 0px 0px 100px"> Planner</h2>

    <div class="plannerHeader" role="row">
    <div class="planner" style="width:160px" >
      <div class="weekOptions" ngbDropdown>
        <div
          class="chevron"
          id="navbarScrollingDropdown"
          ngbDropdownToggle
          data-no-icon="true"
        >
          <span *ngIf="!display">Week {{ date | date: 'w' }}</span>
          <span *ngIf="display">{{ selectedWeek }}</span>
        </div>
        <ul
          class="dropdown-menu"
          ngbDropdownMenu
          aria-labelledby="navbarScrollingDropdown"
        >
          <li
            ngbDropdownItem
            *ngFor="let week of weeks"
            class="dropdown-item"
            (click)="changeWeek(week)"
          >
             <div>{{ week }}</div>
           </li>
        </ul>
      </div>
    
    </div>
      <div class="plannerBottom">
        <p>
          From <b>{{ selectedWeek | date: 'd MMMM yyyy' }}</b> to
          <b>{{ selectedWeek | date: 'd MMMM yyyy' }}</b>
        </p>
      </div>
    </div>

Here is my working demo StackBlitz.


Solution

  • I've made changes to make this work as you have explained, I have forked your StackBlitz project so you can see the updated version here.

    The key changes are how the click event for the line item and how the week list is generated. The list that is generated uses an array of objects (which has a date and a label).

    Moving the selected date into its own state and adding a separate function to handle the population of the date information (start and end of the week) allows the logic of generating a list of weeks easier and a one-off operation.