I have a JS code which is supposed to show sequentially messages sent class. There is class called Message Service. It implement the logic for showing a text message through class method showMessage(). It takes 2 seconds for message fading in and fading out. The logic assumes that if there is a new message sent while service for the previous message is not completed than it adds message to the queue. Then setTimeOut function checks if queue is not empty and if it is not it calls message service on first queue item.
The problem is that on first iteration of the service the code can’t get access to class variables this.service and this.messageStack and this.targetStack. It shows undefined. How can I get access to this.service and this.messageStack and this.targetStack variables in setTimeOut function, which recurcevely calls showMessage() method?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="show-message">Show message</button>
<div id="holder">
</div>
<script>
class MessageService {
constructor() {
this.service = 0;
this.messageStack = []
this.targetStack = []
console.log('initiated')
}
showMessage(target, msg) {
this.target = target
this.msg = msg
console.log(this.target + ' ' + this.msg)
if (this.service === 0) {
console.log('here')
this.service = 1
let el = document.createElement('div')
el.setAttribute('id', 'thisMessage')
el.innerText = this.msg
let elStyle = document.createElement('style')
elStyle.innerHTML = ` #thisMessage {
border: 1px solid purple;
border-radius: 3px;
width: 200px;
height: 20px;
display: flex;
align-items: center;
background-color: rgb(245, 202, 245);
padding: 5px;
padding-left: 10px;
animation: fadeinout 2s linear forwards;
-webkit-animation: fadeinout 2s linear forwards;
opacity: 0;
margin-top: 20px;
}
@keyframes fadeinout {
50% {
opacity: 1;
}
}
@-webkit-keyframes fadeinout {
0%,
100% {
opacity: 0;
}
50% {
opacity: 1;
}
}`
el.appendChild(elStyle)
document.getElementById(target).appendChild(el)
console.log(this.messageStack)
setTimeout(function () {
document.getElementById('thisMessage').remove();
this.service = 0
console.log(this.messageStack) // UNDEFINED ??????
if (this.messageStack.length >
0) { // CANNOT READ PROPERTIES OF UNDERFINED (READING "LENGTH") ?????
let newMessage = this.messageStack.pop()
let newTarget = this.targetStack.pop()
func.call.this.showMessage(newTarget, newMessage)
}
}, 2100)
} else {
this.messageStack.push(this.msg)
this.targetStack.push(this.target)
}
}
}
let msg = new MessageService();
msg.showMessage('holder', 'Print out all papers')
msg.showMessage('holder', 'Update completed')
msg.showMessage('holder', 'Server error')
</script>
</body>
<style>
</style>
</html>