Thanks for seeing my post!
This is the procedure that I used but the orignal help is from T.J
I have solved my problem by changing my mechanism. I took following steps to solve my problem:
- I saved a json file instead of the previous array exported by a js file.
- Then in .get() api I read that file from fs.readFileSync() and parsed it by JSON.parse() and returned the array in that json format.
Here is the code:
Arrays/bookFiles.json
:
{
"name":"bookFiles",
"array":[["CSSNotesForProfessionals.pdf","/mnt/Data/Books/CSSNotesForProfessionals.pdf","pdf","application/pdf"],["JS for Beginners.pdf","/mnt/Data/Books/JS for Beginners.pdf","pdf","application/pdf"],["alqamoosulwaheed.pdf","/mnt/Data/Books/alqamoosulwaheed.pdf","pdf","application/pdf"]]
}
routes/book.mjs
:
import express from "express";
import * as fs from 'fs'
export const book = express.Router();
// import { bookFiles } from "../Arrays/bookFiles.mjs";
book.get("/",(req,res)=>{
const data = JSON.parse(fs.readFileSync('/home/abdurehman/LocalNas/backend/Arrays/bookFiles.json','utf-8'))
res.send(data.array)
}
)
Previous Issue:
Below is my array which is changed by another script after some time
export const bookFiles=[]
I have imported it in my main Express JS + Node JS route for an api, But the problem is that when I run the script it takes and remembers the values in the array and provide that to the api fetch. But I want it to re-import or re-scan the array and send it to the API fetch.
Router File:
routes/book.mjs:
import express from "express";
export const book = express.Router();
import { bookFiles } from "../Arrays/bookFiles.mjs";
book.get("/",(req,res)=>{
const data=bookFiles
res.send(data)
}
)
And this is my Main File
/app.mjs:
import express from 'express';
import { zip } from './routes/zip.mjs';
import { office } from './routes/office.mjs';
import { compressed } from './routes/compressed.mjs';
import { image } from './routes/images.mjs';
import { book } from './routes/book.mjs';
import { videos } from './routes/videos.mjs';
var app = express()
app.use("/zipFiles",zip)
app.use("/officeFiles",office)
app.use("/videoFiles",videos)
app.use("/compressedFiles",compressed)
app.use("/bookFiles",book)
app.use("/imageFiles",image)
app.listen("5000")
I also tried to instead readFileSync from .js file and then parse it into Array, but it didn’t worked because JSON.parse() does not support it. Thanks for the cooperation.
As Asked this is the code that changes the text of Arrays/*
:
/fmgr.mjs
:
import * as fs from 'fs';
import {fileTypeFromFile} from 'file-type';
import * as path from 'path';
import * as url from 'url';
var compressedFiles = [];
var imageFiles = [];
var videoFiles = [];
var undefinedFiles = [];
var bookFiles = [];
var zipFiles = [];
var officeFiles = [];
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
async function chaosofFiles() {
const getAllFiles = function (dirPath, arrayOfFiles) {
const files = fs.readdirSync(dirPath)
arrayOfFiles = arrayOfFiles || []
files.forEach(function (file) {
if (fs.statSync(dirPath + "/" + file).isDirectory()) {
arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles)
} else {
arrayOfFiles.push(path.join(dirPath, "/", file))
}
})
// console.log(arrayOfFiles)
return arrayOfFiles
}
const myFiles = [];
getAllFiles("/mnt/Data", myFiles)
// const files_with_type = [];
// const type = await fileTypeFromFile(myFiles.at(0))
// console.log(type)
// // Determing the type of files
const filesextensions = await Promise.all(myFiles.map(async (file) => {
const type = await fileTypeFromFile(file);
const name = file.split('\').pop().split('/').pop();
let array = [];
if (type == undefined) {
array = [name, file, "undefined", "undefined"]
} else {
array = [name, file, type.ext, type.mime];
}
// const files_with_type
return array;
// console.log(filesextensions)
})
)
// console.log(files_with_type)
console.log("This it the finaln")
// console.log(filesextensions);
compressedFiles = [];
imageFiles = [];
videoFiles = [];
undefinedFiles = [];
bookFiles = [];
zipFiles = [];
officeFiles = [];
filesextensions.forEach(function (array) {
const mime = array.at(3);
// console.log('Cureent '+{mime})
// console.log('Array n '+{array})
const ext = array.at(2);
// console.log('Cureent '+{ext})
if (ext.includes("zip")) {
zipFiles.push(array)
} else if (mime.includes("image")) {
imageFiles.push(array)
} else if (mime.includes("compressed")) {
compressedFiles.push(array)
} else if (mime.includes("video")) {
videoFiles.push(array)
} else if (mime == "undefined") {
undefinedFiles.push(array)
} else if (mime.includes("office")) {
officeFiles.push(array)
}
else if (mime.includes("pdf")) {
bookFiles.push(array)
}
}
)
// console.log({zipFiles})
// console.log({compressedFiles})
// console.log({officeFiles})
// console.log({videoFiles})
const arrayGroup = [
{ name: "compressedFiles", array: compressedFiles },
{ name: "imageFiles", array: imageFiles },
{ name: "videoFiles", array: videoFiles },
{ name: "zipFiles", array: zipFiles },
{ name: "officeFiles", array: officeFiles },
{ name: "bookFiles", array: bookFiles },
{ name: "undefinedFiles", array: undefinedFiles }
]
// console.log("Current dir is ",__dirname)
arrayGroup.forEach(
function (array) {
console.log(array)
fs.writeFile(__dirname + "Arrays/" + array.name + ".mjs", "export const " + array.name + "= ()=>{ return " + JSON.stringify(array.array)+";}", function (err) {
if (err) {
return console.log(err);
}
});
}
)
}
chaosofFiles()
async function waitUntil() {
return await new Promise(resolve => {
var i = 0;
const interval = setInterval(() => {
resolve('foo');
chaosofFiles()
i = i + 1;
}, 10000);
});
}
waitUntil()
2
Answers
I think you’re saying that while your web server process is running, you have another process that periodically replaces the
../Arrays/bookFiles.mjs
file, and you want to see those changes.JavaScript modules don’t work that way. A module is read once during program execution.
If you want to re-read the file on each request (or when it changes), don’t make it a module. Instead, make it a JSON file you re-write as necessary, and have your web process read and parse the JSON file on startup or when it changes. You might export a function that will get the array, cache it and remember the file date/time, and reuse the array as long as the file date/time hasn’t changed but re-read it when it has. Then you’d call that function in your route handler that returns the array.
Is there a reason you are not utilizing express.static middleware?
If there is a reason to read the file, then process it, it would still be much better to store these files as
.json
.Assuming you don’t want to utilize static files…
You are already using
JSON.stringify
in yourfs.writeFile
call, why not just use: