code after var fs = require('fs') not running - javascript

Why does my simple jquery not run after the var fs = require('fs') code.
This runs correctly
//here is my simple jquery
$("#table th").css("color", "yellow");
//here starts the fs code
var fs = require('fs');
var output = fs.readFileSync('component names.txt', 'utf8').replace(/(\r)/gm, "").split('\n').map((line) => {
let [Eng, Spa, ger] = line.split('\t');
return {
Eng,
Spa,
ger
};
});
var Eng = output.map(item => item.Eng);
var Spa = output.map(item => item.Spa);
However if I put the $("#table th").css("color", "yellow") at the bottom, where I want it because I'm going to populate a table, it doesn't work here:
var fs = require('fs');
var output = fs.readFileSync('component names.txt', 'utf8').replace(/(\r)/gm, "").split('\n').map((line) => {
let [Eng, Spa, ger] = line.split('\t');
return {
Eng,
Spa,
ger
};
});
var Eng = output.map(item => item.Eng);
var Spa = output.map(item => item.Spa);
//jquery
$("#table th").css("color", "yellow");
Why?

I would suspect it having something to do with the readFileSync function.
Try wrapping it with a try catch, see if it catches anything.
You said that the first code works, but I think you were referring to the jquery code. I believe that the fs code is not functioning properly.
try {
var output = fs.readFileSync('component names.txt', 'utf8').replace(/(\r)/gm, "").split('\n').map((line) => {
let [Eng, Spa, ger] = line.split('\t');
return {
Eng,
Spa,
ger
};
});
var Eng = output.map(item => item.Eng);
var Spa = output.map(item => item.Spa);
} catch(e) {
console.error(e) //see what's going on here
}
If you do this, the jquery code will work, because whatever error is happening will be caught and ignored, so it's very important to debug the code to not run into any future problems

Related

Javascript working in Chrome, working in firefox locally, but not after deployment

This is part of a Spark Java app, but the error is happening in this JS part. The relevant code is as follows:
const addErrBox = async () => {
const controls = document.querySelector(".pure-controls");
const errBox = document.createElement("p");
errBox.setAttribute("id", "errBox");
errBox.setAttribute("style", "color:red");
errBox.innerHTML = "Short URL not valid or already in use!";
controls.appendChild(errBox);
}
const submitForm = () => {
const form = document.forms.namedItem("new-url-form");
const longUrl = form.elements["longUrl"];
const shortUrl = form.elements["shortUrl"];
const url = `/api/new`;
fetch(url, {
method: "POST",
body: `${longUrl.value};${shortUrl.value}`
})
.then((res) => {
if (!res.ok) {
if (document.getElementById("errBox") == null) {
addErrBox();
}
}
else {
document.getElementById("errBox")?.remove();
longUrl.value = "";
shortUrl.value = "";
refreshData();
}
});
};
(async () => {
await refreshData();
const form = document.forms.namedItem("new-url-form");
form.onsubmit = e => {
e.preventDefault();
submitForm();
}
})();
Basically, "/api/new" checks for validity of input, adds the data to database if valid and prints error otherwise. Now, when the input is valid, it seems to work. The "/api/new" code is in Java, which seems to work properly as well since I do get a 400 error. All of it works properly when built inside a docker locally, but when accessed over internet using Nginx reverse proxy, it stops working inside firefox. Chrome still works. I'm not sure what's happening.
The code for "/api/new" is this:
public static String addUrl(Request req, Response res) {
var body = req.body();
if (body.endsWith(";")) {
body = body + "$";
}
var split = body.split(";");
String longUrl = split[0];
if (split[1].equals("$")) {
split[1] = Utils.randomString();
}
String shortUrl = split[1];
shortUrl = shortUrl.toLowerCase();
var shortUrlPresent = urlRepository
.findForShortUrl(shortUrl);
if (shortUrlPresent.isEmpty() && Utils.validate(shortUrl)) {
return urlRepository.addUrl(longUrl, shortUrl);
} else {
res.status(HttpStatus.BAD_REQUEST_400);
return "shortUrl not valid or already in use";
}
}
Update: it suddenly started working, without any change on the server side. I think it was some kind of issue with caching, either in firefox, cloudflare or Nginx's part.

Converting AVVideoComposition initializer to Nativescript

Looking for some help on porting this objective-c class method to JS/nativescript.. every variation I've tried has resulted in a TypeError: undefined is not a function...
https://developer.apple.com/documentation/avfoundation/avvideocomposition/1389556-init
Which I've tried to write in JS as:
const videoComp = AVVideoComposition.alloc().initWithAssetApplyingCIFiltersWithHandler(asset, (request) => { ... });
//OR
const videoComp = AVVideoComposition.alloc().initAssetApplyingCIFiltersWithHandler(asset, (request) => { ... });
//OR
const videoComp = AVVideoComposition.alloc().initAssetApplyingCIFiltersWithHandlerApplier(asset, (request) => { ... });
//OR
const videoComp = new AVVideoComposition(asset, (request) => { ... });
to name a few. essentially, I am trying to port this code to nativescript/JS:
let blurRadius = 6.0
let asset = AVAsset(url: streamURL)
let item = AVPlayerItem(asset: asset)
item.videoComposition= AVVideoComposition(asset: asset) { request in
let blurred = request.sourceImage.clampedToExtent().applyingGaussianBlur(sigma: blurRadius)
let output = blurred.clampedToRect(request.sourceImage.extent)
request.finish(with: output, context: nil)
}
found in this blog post: https://willowtreeapps.com/ideas/how-to-apply-a-filter-to-a-video-stream-in-ios
It should look something like this with JavaScript / Typescript,
let blurRadius = 6.0;
let asset = AVAsset.assetWithURL(streamURL);
let item = AVPlayerItem.alloc().initWithAsset(asset);
item.videoComposition = AVVideoComposition.videoCompositionWithAssetApplyingCIFiltersWithHandler(asset, request => {
let blurred = request.sourceImage.imageByClampingToExtent().imageByApplyingGaussianBlurWithSigma(blurRadius);
let output = blurred.imageByClampingToRect(request.sourceImage.extent);
request.finishWithImageContext(output, null);
});
Note: The code is untested and merely a translation of given native code. Make use of tns-platform-declarations for IntelliSense support.

Return list of Objects with Node js

I recently started development of a Node js application and it uses Selenium in a controller to fetch list of items from a web page and I want to return the fetched list of items as a JSON response.
exports.read_all_products = function (req, res) {
var driver = new webdriver.Builder().forBrowser('phantomjs').build();
driver.get('https://www.test.com/products?PC=' +req.params.category);
driver.wait(until.elementLocated(By.className('product-slide-all')), 20000, 'Could not locate the element within the time specified');
driver.findElements(By.className("product-slide-all")).then(function (elements) {
var arr = [];
elements.forEach(function (element) {
element.getAttribute("innerHTML").then(function (html) {
const dom = new JSDOM(html);
var obj = new Object();
obj.product_name = dom.window.document.querySelector(".product-name").textContent;
obj.product_code = dom.window.document.querySelector(".product-code").textContent;
obj.price = dom.window.document.querySelector(".product-price").textContent;
arr.push(obj);
});
});
res.json(arr);
});
}
Issue is I am always getting an empty JSON response even though items were added to the array. I want to know the proper way of handling this scenario.
Thanks.
It looks like the issue is because Selenium is running an async process, thus the response immediately returns because there is nothing blocking it.
findElements returns a Promise which you need to return the response from.
Take a look at How do I return the response from an asynchronous call?
Finally I was able to get it work with the help of webdriver.promise.map.
Moved web driver HTML extraction to separate function.
var findItems = function (category) {
var driver = new webdriver.Builder().forBrowser('phantomjs').build();
var map = webdriver.promise.map;
driver.get('https://www.test.com?PC=' + category);
driver.wait(until.elementLocated(By.className('product-slide-all')), 30000, 'Could not locate the element within the time specified');
var elems = driver.findElements(By.className("product-slide-all"));
return map(elems, elem => elem.getAttribute("innerHTML")).then(titles => {
return titles;
});
}
then call it from response handling function like bellow,
exports.read_all_products = function (req, res) {
findItems(req.params.category).then(function (html) {
var value;
var arr = [];
Object.keys(html).forEach(function (key) {
value = html[key];
const dom = new JSDOM(value);
var obj = new Object();
obj.product_name = dom.window.document.querySelector(".product-name").textContent;
obj.product_code = dom.window.document.querySelector(".product-code").textContent;
obj.price = dom.window.document.querySelector(".product-price").textContent;
arr.push(obj);
});
res.json(arr);
})
};
it's described in this stack overflow answers.

How can I rewrite this while loop in a JSLint-approved way?

Looking at the the "Streams 2 & 3 (pull) example" from: https://github.com/jprichardson/node-fs-extra#walk
var items = [] // files, directories, symlinks, etc
var fs = require('fs-extra')
fs.walk(TEST_DIR)
.on('readable', function () {
var item
while ((item = this.read())) {
items.push(item.path)
}
})
.on('end', function () {
console.dir(items) // => [ ... array of files]
})
Latest version of JSLint complaints about the while:
Unexpected statement '=' in expression position.
while ((item = this.read())) {
Unexpected 'this'.
while ((item = this.read())) {
I'm trying to figure out how to write this in a JSLint-approved way. Any suggestions?
(Note: I'm aware there are other JSLint violations in this code ... I know how to fix those ...)
If you're really interested in writing this code like Douglas Crockford (the author of JSLint), you would use recursion instead of a while loop, since there are tail call optimizations in ES6.
var items = [];
var fs = require("fs-extra");
var files = fs.walk(TEST_DIR);
files.on("readable", function readPaths() {
var item = files.read();
if (item) {
items.push(item.path);
readPaths();
}
}).on("end", function () {
console.dir(items);
});

GJS read file synchronously

I'm trying to use GJS and more precisely
to read a text file in a synchronous way.
Here is an example an the asynchronous function for file reading
gio-cat.js
I found how to proceed with seed using the next function:
function readFile(filename) {
print(filename);
var input_file = gio.file_new_for_path(filename);
var fstream = input_file.read();
var dstream = new gio.DataInputStream.c_new(fstream);
var data = dstream.read_until("", 0);
fstream.close();
return data;
}
but unfortunately, it doesn't work with GJS.
Can anyone help me ?
GLib has the helper function GLib.file_get_contents(String fileName) to read files synchronously:
const GLib = imports.gi.GLib;
//...
let fileContents = String(GLib.file_get_contents("/path/to/yourFile")[1]);
Here is a solution that works with just Gio.
function readFile(filename) {
let input_file = Gio.file_new_for_path(filename);
let size = input_file.query_info(
"standard::size",
Gio.FileQueryInfoFlags.NONE,
null).get_size();
let stream = input_file.open_readwrite(null).get_input_stream();
let data = stream.read_bytes(size, null).get_data();
stream.close(null);
return data;
}
As I use GJS for developing Cinnamon applets, I used to use the get_file_contents_utf8_sync function to read text files :
const Cinnamon = imports.gi.Cinnamon;
let fileContent = Cinnamon.get_file_contents_utf8_sync("file path");
If you have Cinnamon installed and you agree to use it, it answers your question.
Otherwise here is the C code of the get_file_contents_utf8_sync function in cinnamon-util.c, hoping this will help you:
char * cinnamon_get_file_contents_utf8_sync (const char *path, GError **error)
{
char *contents;
gsize len;
if (!g_file_get_contents (path, &contents, &len, error))
return NULL;
if (!g_utf8_validate (contents, len, NULL))
{
g_free (contents);
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"File %s contains invalid UTF-8",
path);
return NULL;
}
return contents;
}
Cinnamon source code
Try replacing
new gio.DataInputStream.c_new(fstream);
with
gio.DataInputStream.new(fstream);
it worked for me

Categories

Resources