I am new in JS and I have a task to implement the functionality to send user click events (clicks on buttons, the email input field) to a web worker. The worker must collect data into the batches of 5 items and send it to the server (using POST /analytics/user) endpoint. The problem is that I don't understand how to collect user clicks and send them into batches of 5 items which I searched for documentation but nowhere is mentioned about batches. Could you help me please? My website has 3 buttons,2 of them doesn't have any event listeners and the last one is used to submit an email, as shown below:
/analytics/user endpoint code from route:
router.post('/user', async function (req, res) {
const payload = req.body;
try {
let data;
try {
data = await FileStorage.readJsonFile('user-analytics.json');
} catch (e) {
data = [];
}
data.push({timestamp: Date.now(), data: payload});
await FileStorage.writeFile('user-analytics.json', data);
await res.json({success: true})
} catch (e) {
console.log(e);
res.status(500).send('Internal error');
}
});
Let me know if I should add more information about something.
Edit :
I wrote the functions to send button clicks and after that the worker should send the data to server, but now the problem is that I can not push messages to web worker to an array ,it pushes only first message..
Function for sending user clicks to the web worker :
export const sendUserClicksToWorker = () => {
const allButtonsToStore = document.getElementsByClassName("app-section__button");
const inputField = document.getElementsByClassName("form-input")
let reason = [];
//for loop for pushing clicks from buttonts to the array
for (let x = 0; x < allButtonsToStore.length; x++) {
allButtonsToStore[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
console.log(this.textContent)
});
}
//for loop for pushing click from email input field to the array
for (let x = 0; x < inputField.length; x++) {
inputField[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
console.log(this.textContent)
});
}
}
Function for sending data to the server :
export const sendButtonClicksToServer = (dataToSend) => {
sendHttpRequest('POST', 'http://localhost:8080/analytics/user', {
dataToSend
}).then(responseData => {
return responseData
//console.log(responseData);
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
And in main js file :
if (window.Worker) {
const url = new URL('./scripts/worker.js', import.meta.url);
const worker = new Worker(url);
const allButtonsToStore = document.getElementsByClassName("app-section__button");
const inputField = document.getElementsByClassName("form-input")
//for loop for pushing clicks from buttonts to the array
for (let x = 0; x < allButtonsToStore.length; x++) {
allButtonsToStore[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
//console.log(this.textContent)
});
}
//for loop for pushing click from email input field to the array
for (let x = 0; x < inputField.length; x++) {
inputField[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
// console.log(this.textContent)
});
}
worker.onmessage = e => {
console.log(e.data)
sendButtonClicksToServer(e.data);
}
worker.onerror = error => {
console.log(error.message)
}
}
And worker.js :
let data = []
onmessage = function (e) {
console.log('Data Received: ',e.data)
let receivedButtonClicks = e.data
// data.push(receivedButtonClicks)
// if (data.length > 4) {
// postMessage(data)
// data.length = 0;
// console.log('Data received!')
// console.log(data)
// }
for ( let i = 0 ; i< 5;i++){
data[i].push(receivedButtonClicks)
}
console.log('blabla',data)
}
Now I don't understand 100% where is the problem and how to fix it??..
So,i managed how to do this task and i came back here showing my functionality :
I did two functions,one for sending user clicks to the webworker in the following way :
const sendUserClicksToWorker = () => {
if (window.Worker) {
const url = new URL('./worker.js', import.meta.url);
const worker = new Worker(url);
const allButtonsToStore = document.getElementsByClassName("app-section__button");
const inputField = document.getElementsByClassName("form-input")
//for loop for pushing clicks from buttonts to the array
for (let x = 0; x < allButtonsToStore.length; x++) {
allButtonsToStore[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
});
}
//for loop for pushing click from email input field to the array
for (let x = 0; x < inputField.length; x++) {
inputField[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
});
}
worker.onmessage = e => {
// console.log('Thread received data: ', e.data)
sendButtonClicksToServer(e.data);
}
worker.onerror = error => {
console.log(error.message)
}
}
}
On every button click it posts a message to the webworker. And the second function for sending data to the server:
const sendButtonClicksToServer = (dataToSend) => {
sendHttpRequest('POST', 'http://localhost:8080/analytics/user', {
dataToSend
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
The webworker procces the data received this way and sends back to the main thread were on next step,it is being send to the server:
let batch = []
onmessage = function (e) {
console.log('Data Received: ',e.data)
let receivedButtonClicks = e.data
for ( let i = 0 ; i< 1;i++){
batch.push(receivedButtonClicks)
if (batch.length > 4){
postMessage(batch)
batch.length = 0
console.log('Data was sent!')
}
}
}
It wasnt that hard,but it took damn too much time. Thanks everyone for help!