Home > other >  Issues updating a local HTML file with parsed data from uploaded HTML files
Issues updating a local HTML file with parsed data from uploaded HTML files

Time:12-07

I'm quite new to this so please bare with me. I'm currently trying to put together an HTML report building tool. I have 2 html reports that are being generated by 3rd parties. I'd like to be able to upload them, parse them, save the specific parse to a variable and update my template which is in a folder on the server.

Currently, I'm using express, and node-html-parser.

I have no issues getting the HTML files uploaded to a directory on the server and parsing those files.

My issue comes in when I try to update the variable I want with the string that I want.

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
 });
};

Now, ideally I'd like to call back this function in a GET request and have it update the variables. From there, I would use those strings to modify a template HTML file that's sitting in a folder on my server. I'd like to be able to replace html elements in the template with those updated variables. Once updated, id push the response to download the file. Every time I try this with a fs.writeFile , it seems to just say the variables 'element1' or 'element2' are empty. I'm not even sure if I can write a local HTML file and save it the same way you'd normally do it with the DOM.

I'm lost at this point. I would assume I'd need to read then write the template html file. but how i'd go about editing it, I have no clue. Also, the variables being empty is stumping me. I know it's due to the fact that fs.readFile is asynchronous, but then how would I go about reading and writing files in the manner I am looking for?

any help would be much appreciated!

CodePudding user response:

You have two possibilities: use fs.readFileSync, which is easy to use but since it 's synchronous, it blocks your thread (and makes your server unresponsive while the files are being read). The more elegant solution is to use the Promise version and to await it.

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);
};

CodePudding user response:

You have two options here. One is to block the thread and wait for each consecutive read to end before ending the function.

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();
}

The other would be to use async and read both files at the same time, then return whenever they both finish:

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();
}
  • Related