Walter White Walter White - 27 days ago 7
TypeScript Question

Dom Element undefined

I have two global property

htmlContentElement
htmlContentContainer


I set it in

ngAfterViewInit() {
this.htmlContentElement = document.getElementById("messageContent");
this.htmlContentContainer = document.getElementById("messageContainer");
}


And i use this prperty in this method

setOcrMessage() {
let originalContent = this.htmlContentElement.innerHTML;
console.log(this.htmlContentElement);
this.htmlContentElement.innerHTML = this.ocrInfo.message;
if(this.ocrInfo.status) {
this.htmlContentElement.style.color = "#168F48";
this.htmlContentContainer.style.background = "rgb(236, 253, 240)";
} else {
this.htmlContentElement.style.color = "#e50000";
this.htmlContentContainer.style.background = "rgb(251, 233, 235)";
}

setTimeout(function() {
console.log(this.htmlContentElement);
this.htmlContentElement.innerHTML = originalContent;
this.this.htmlContentElement.style.color = "#979797";
this.htmlContentContainer.style.background = "white";
this.htmlContentContainer.style.opacity = "1";
}, 3000);
}
}


first console.log(this.htmlContentElement) return element
but second in setTimeout() return undefined

I execute setOcrMessage() in

constructor( private imageService: ImageService, private documentService: DocumentService,
private ocrService: OcrService) {
this.ocrMessageSubscription = this.ocrService.messageIfOcrCorrectly.subscribe(
(res: ocrMessage) => {
this.ocrInfo = res;
this.setOcrMessage();
}
)
}


Why htmlContentElement become undefined?
When i use
htmlContentElement and
htmlContentContainer
property local in setOcrMessage() everything work fine.

Answer Source

Because you are losing the closure by using function, instead of

setTimeout(function() {
      console.log(this.htmlContentElement);
      this.htmlContentElement.innerHTML = originalContent;
      this.this.htmlContentElement.style.color = "#979797";
      this.htmlContentContainer.style.background = "white";
      this.htmlContentContainer.style.opacity = "1";
    }, 3000);

try to use arrow function

setTimeout(() => {
      console.log(this.htmlContentElement);
      this.htmlContentElement.innerHTML = originalContent;
      this.this.htmlContentElement.style.color = "#979797";
      this.htmlContentContainer.style.background = "white";
      this.htmlContentContainer.style.opacity = "1";
    }, 3000);