简体   繁体   中英

How to fix : Cannot set property 'innerHTML' of null error in Angular 6?

I want to create a custom calendar in my app. While developing code in JavaScript it worked. After when I tried to migrate my code to Angular 6 it is not working properly. Angular throwing a run-time error. Which I'm not able to resolve,

Anyone please help me with this!

This is the Stack-Blitz link which I'm working on : StackBlitz !

showCalendar(month, year) {
const firstDay = (new Date(year, month)).getDay();
const daysInMonth = 32 - new Date(year, month, 32).getDate();

console.log('\n val \n' + new Date(year, month, 32).getDate());

const tbl = document.getElementById('calendar-body');

// clearing all previous cells
tbl.innerHTML = '';

// filing data about month and in the page via DOM.
this.monthAndYear.innerHTML = this.months[month] + ' ' + year;

 // creating all cells
let date = 1;
for (let i = 0; i < 6; i++) {
    const row = document.createElement('tr');

    for (let j = 0; j < 7; j++) {
        // let cell = document.createElement('td');
        if (i === 0 && j < firstDay) {
            const cell = document.createElement('td');
            const cellText = document.createTextNode('');
            cell.appendChild(cellText);
            row.appendChild(cell);
        } else if (date > daysInMonth) {
            break;
        } else {
            const cell = document.createElement('td');
            const cellText = document.createTextNode(date.toString());
        if (date === this.today.getDate() && year === this.today.getFullYear() && month === this.today.getMonth()) {
            // cell.classList.add("bg-info");
        } // color todays date
            date++;
        }
    }
    tbl.appendChild(row); // appending each row into calendar body.
  }
}

constructor() {
 this.today = new Date();
 this.currentMonth = this.today.getMonth();
 this.currentYear = this.today.getFullYear();
 this.monthAndYear = document.getElementById('monthAndYear');
}

ngOnInit() {
 this.showCalendar(this.currentMonth, this.currentYear);
 console.log('ngOnInit');
}

Expected result is It show a calendar.

But it is giving the error as: ERROR TypeError: Cannot set property 'innerHTML' of null at CustomCalendarComponent.push../src/app/components/custom-calendar/custom-calendar.component.ts.CustomCalendarComponent.showCalendar (custom-calendar.component.ts:67)

Move document.getElementByid('monthAndYear') to ngOnInit since there is no attached DOM yet when contructor is called.

https://stackblitz.com/edit/angular-yzzvsb?file=src/app/app.component.ts

Besides that, the entire calendar generation logic is broken so you will have to work on it. Rows and cells are added. However, why you set them as empty is a mystery.

Angular use separate API for manipulate DOM.The Renderer2 provided by Angular in the form of a service that allows to manipulate elements of your app without having to touch the DOM direct

If you want to Select specific element from DOM use template variable, then use ViewChild decorator to access the element inside component class

component.html

<h3 class="card-reader" id="monthAndYear" #monthAndYear> Month and Year</h3>

component.ts

@ViewChild('monthAndYear') monthAndYear: ElementRef;

Create New element Use Renderer2

      constructor(private ren: Renderer2) {}
      const cell = this.ren.createElement('td');
      const cellText = this.ren.createText('');
      cell.appendChild(cellText);

Ref: https://alligator.io/angular/using-renderer2/

Forked Example: https://stackblitz.com/edit/angular-up1ibg

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM