Soy bastante nuevo en esto, así que por favor, sé sincero conmigo. Actualmente estoy tratando de armar una herramienta de creación de informes HTML. Tengo 2 informes html generados por terceros. Me gustaría poder cargarlos, analizarlos, guardar el análisis específico en una variable y actualizar mi plantilla que se encuentra en una carpeta en el servidor.
Actualmente, estoy usando express y node-html-parser.
No tengo problemas para cargar los archivos HTML en un directorio en el servidor y analizar esos archivos.
Mi problema surge cuando trato de actualizar la variable que quiero con la cadena que quiero.
const fs = require('fs'); const htmlparse = require('node-html-parser').parse; var element1 var element2 function datatoString(){ fs.readFile(__dirname + "/api/upload/" + file1, 'utf8', (err,html)=>{ const root = htmlparse(html); head = root.querySelector('head'); element1 = head.toString(); console.log("-------------break------------") console.log(head.toString()); //This works and shows me my parsed info }); fs.readFile(__dirname + "/api/upload/" + file2, 'utf8', (err,html)=>{ const root = htmlparse(html); body = root.querySelector('body'); element2 = body.toString(); console.log("-------------break------------") console.log(body.toString()); //This works and shows me my parsed info }); };Ahora, idealmente me gustaría volver a llamar a esta función en una solicitud GET y hacer que actualice las variables. A partir de ahí, usaría esas cadenas para modificar un archivo HTML de plantilla que se encuentra en una carpeta en mi servidor. Me gustaría poder reemplazar elementos html en la plantilla con esas variables actualizadas. Una vez actualizado, identifique la respuesta para descargar el archivo. Cada vez que intento esto con un fs.writeFile, parece que simplemente dice que las variables 'element1' o 'element2' están vacías. Ni siquiera estoy seguro de poder escribir un archivo HTML local y guardarlo de la misma manera que normalmente lo haría con el DOM.
Estoy perdido en este punto. Asumiría que necesitaría leer y luego escribir el archivo html de la plantilla. pero cómo haría para editarlo, no tengo ni idea. Además, el hecho de que las variables estén vacías me deja perplejo. Sé que se debe al hecho de que fs.readFile es asíncrono, pero entonces, ¿cómo haría para leer y escribir archivos de la manera que estoy buscando?
cualquier ayuda sería muy apreciada!
Tiene dos posibilidades: use fs.readFileSync , que es fácil de usar pero, dado que es síncrono, bloquea su hilo (y hace que su servidor no responda mientras se leen los archivos). La solución más elegante es usar la versión Promise y esperarla.
const promises = require('fs').promises; const htmlparse = require('node-html-parser').parse; let element1, element2; async function datatoString() { let html = await promises.readFile(__dirname + "/api/upload/" + file1, 'utf8'); let root = htmlparse(html); head = root.querySelector('head'); element1 = head.toString(); console.log("-------------break------------") console.log(element1); html = await promises.readFile(__dirname + "/api/upload/" + file2, 'utf8'); root = htmlparse(html); body = root.querySelector('body'); element2 = body.toString(); console.log("-------------break------------") console.log(element2); };Tienes dos opciones aquí. Una es bloquear el hilo y esperar a que finalice cada lectura consecutiva antes de finalizar la función.
function datatoString() { let element1, element2; fs.readFileSync(... element1 = 'foo'}); fs.readFileSync(... element2 = 'bar'}); return [element1, element2]; } app.get('/example', (req, res) => { ... const [element1, element2] = datatoString(); }La otra sería usar async y leer ambos archivos al mismo tiempo, luego regresar cuando ambos terminen:
function datatoString() { return new Promise((resolve, reject) => { let element1, element2; fs.readFile(... element1 = 'foo', if (element2) resolve([element1, element2]);}); fs.readFile(... element2 = 'bar', if (element1) resolve([element1, element2]);}); }); } app.get('/example', async (req, res) => { ... const [element1, element2] = await datatoString(); }