I’m pretty new to this, and I’m having trouble getting the output I’m looking for. I have a web page where I’d like to display my CSV in a nice looking table. The output is not being displayed on the web page at all when I access the local port. When I go to inspect and then the network tab, I can see that the GET to /data is working. It returns 200, type JSON, and I see the JSON body. Where is the point that’s going wrong? Inspect shows JSON returned and logs show ‘sending data in res.json’ but no ‘fetch’ (from script.js). Clearly never got there, but why is that and how can I fix it?
script.js:
// Function to fetch CSV data from the server and render it as a table
const fetchAndRenderCSV = async () => {
try {
console.log('trying fetch /data')
const response = await fetch('/data');
console.log('Response is: ' + response)
const csvData = await response.json();
console.log(csvData)
renderCSVTable(csvData);
} catch (error) {
console.error('Error fetching CSV data:', error);
}
};
// Function to render CSV data as a table
const renderCSVTable = (data) => {
const tableContainer = document.getElementById('csvTableContainer');
const tableHTML = generateTableHTML(data);
tableContainer.innerHTML = tableHTML;
};
// Function to generate HTML for the table
const generateTableHTML = (data) => {
let tableHTML = '<table>';
// Assuming the first row contains headers
tableHTML += '<tr>';
for (let i = 0; i < data[0].length; i++) {
tableHTML += `<th>${data[0][i]}</th>`;
}
tableHTML += '</tr>';
// Add rows for each data entry (excluding the header row)
for (let i = 1; i < data.length; i++) {
tableHTML += '<tr>';
for (let j = 0; j < data[i].length; j++) {
tableHTML += `<td>${data[i][j]}</td>`;
}
tableHTML += '</tr>';
}
tableHTML += '</table>';
return tableHTML;
};
const submitGuess = async () => {
try {
// Clear result and error messages
resultMessage.textContent = '';
errorMessage.textContent = '';
const inputValue = userInput.value.trim();
if (inputValue === '') {
errorMessage.textContent = 'Please enter a name before submitting.';
return;
}
const response = await fetch('/handleInput', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ userInput: inputValue }),
});
const data = await response.json();
if (data.isCorrect) {
resultMessage.textContent = 'Correct answer!';
resultMessage.classList.add('correct-answer');
} else {
// Shake animation on incorrect guess
userInput.classList.add('shake');
// Remove the 'shake' class after the animation ends
userInput.addEventListener('animationend', () => {
userInput.classList.remove('shake');
});
resultMessage.textContent = 'Incorrect answer.';
resultMessage.classList.remove('correct-answer'); // Remove the class if present
}
userInput.value = '';
} catch (error) {
console.error('Error:', error);
}
};
// Call the function to fetch and render CSV data when the page loads
console.log('fetch')
fetchAndRenderCSV();
styles.css:
body {
font-family: Arial, sans-serif;
text-align: center;
}
#game {
margin: 20px auto;
max-width: 400px;
}
#word {
font-size: 2em;
margin-bottom: 20px;
}
#guess {
padding: 5px;
font-size: 1.2em;
width: 100px;
margin-bottom: 10px;
}
#feedback {
margin-top: 20px;
font-weight: bold;
}
@keyframes shake {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-5px);
}
100% {
transform: translateX(0);
}
}
.shake {
animation: shake 0.4s ease-in-out;
}
index.html
<h1>Guess</h1>
<div id="csvTableContainer"></div>
<!-- This is where the table will be rendered -->
<form id="guessForm">
<label for="userInput">Enter Guess:</label>
<input type="text" id="userInput" name="userInput" required>
<button type="button" onclick="submitGuess()" id="submitButton">Submit</button>
</form>
<button onclick="playAgain()" id="playAgainButton">Play Again</button>
<!-- Result message with inline style for correct answer -->
<p id="resultMessage" style="color: green;"></p>
<!-- Error message -->
<p id="errorMessage" style="color: red;"></p>
My server.js:
const puppeteer = require('puppeteer');
const fs = require('fs');
const Papa = require('papaparse');
// const Parse = require('parse');
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const { spawn } = require('child_process');
const app = express();
const port = 3000;
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
let isCorrect = false;
let answer, filePath;
app.get('/data', (req, res) => {
try {
// Read CSV file
const csvData = fs.readFileSync(filePath, 'utf8');
// Parse CSV data
const parsedData = Papa.parse(csvData, { header: true }).data;
// Send parsed CSV data as JSON
console.log('sending data in res.json')
const ret = res.json(parsedData);
// console.log(ret)
} catch (error) {
console.error('Error reading or parsing CSV file:', error);
res.status(500).send('Internal Server Error');
}
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
generateCorrectAnswer();
console.log('The correct answer is: ', answer)
console.log('filePath is: ' + filePath)
checkFileExists(filePath)
readAndParseCSV(filePath);
});
2
Answers
It looks like you weren’t actually calling your
fetchAndRenderCSV()
function. In the below snippet I modified the function a little bit to digest a CSV-type input (instead of the pre-processed JSON) and at the end of the snippet I actually call the rendering function:I also modified the fetch-URL in order to have a workable snippet here in SO.
You certainly need to include
submitGuess()
to fire off the whole process.You should create smaller reduced cases for the best answers.
You may find constructing DOM nodes easier with methods like: