Issue
Unable to load local JSON file in a javascript file which is spun up with node.
Details
The question is straight forward but I am not serving the javascript file in a browser. I have a javascript file which has the logic, I then spin it up with:
node main.js
I googled a few solutions, they recommend using JQuery or XMLHttpRequest but they appear to be running into issues related to the fact i am no serving this in a browser.
Project Background
I am using a raspberry PI to get data from an IR Temperature Sensor. I am using python to get calculate the voltage, convert to celsius, then export that as a JSON file. I then plan to load this file into my javascript file which then configures angular fire Database and pushes this data.
I have a front-end application that will then pull this down and display the end data to the user.
If I go with the JQuery:
Option 1
sample:
$.getJSON("test.json", function(json) {
console.log(json); // this will show the info it in firebug console
});
Error
$.getJSON is not a function even though I am requiring jQuery.
Option 2
If I go with pure javascript, I see
sample
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'my_data.json', true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
Error
xobj.overrideMimeType is not a function
TL/DR
How do I load a local JSON file into a javascript file that is not loaded into a browser but instead spun up with node,
node main.js
Node.js can load JSON files through require. See the documentation here: https://nodejs.org/api/modules.html#modules_all_together
If filename begins with './' or '/' or '../'
If filename.json is a file, parse filename.json to a JavaScript Object. STOP
Most likely what you want is const json = require('./test.json') assuming test.json is in the same directory as the code requiring it. Remember that require parses the JSON, so json in the example is a JavaScript Object.
Related
I have tried different approaches to read a text file from the local file system in JavaScript and display the content of the file in alert() but all to no avail.
Approach 1
function readTextFile(file) {
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file , false);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
var allText = rawFile.response;
document.getElementById("content").innerText = allText;
alert(allText);
}
} else {
alert("Can't read the file");
}
}
rawFile.send(null);
}
readTextFile("FormulaQuestion.txt");
The FormulaQuestion.txt file is in the same directory with the html file, this approach shows an empty alert window on the browser
Approach 2 using fetch method
fetch('FormulaQuestion.txt')
.then(response => response.text())
.then((data) => {
alert(data);
})
This doesn't show anything
Approach 3 using JQuery
$.get('FormulaQuestion.txt', function (data) {
alert(data)
}, 'text');
This doesn't work either.
I am building a desktop application that uses a web browser control to load html file which is embedded into the application. The application reads the string from sqlite database and save it in the FormulaQuestion.txt file, then refreshes the WebControl component which reloads the html file.
Now when the html file is reloaded, the JavaScript should read the text file and display it on alert() which once the alert is able to display the file content, i will then set it to a paragraph and remove the alert().
Please someone should help me out.
Browsers by design do not allow access to the file system for JavaScript, as allowing such access would be a serious security concern.
To provide the FormulaQuestion.txt file to your script you will need to host the file on a server and request it via a HTTP request (like with your fetch). The key thing here is that a server is needed to actually transmit the file over the HTTP protocol to your script.
If working locally, there are many options for running a local server.
The npm serve module,
Wamp
Apache
You may also want to try out some free tier services like Vercel or Netlify. Both I believe allow you to just drag/drop a file and it will host it for you.
Instead of using jQuery here I am trying to use Javascript to load several .php files to
display data from the database according to the user's input. Below is an example of how my functions are like (and most of which are similar):
let userinput = document.getElementById("input");
button_1.onclick = function()
{
let xhr = new XMLHttpRequest();
xhr.open("GET", "ajax/highscore.php?q="+userinput.value, true);
// send the "username" to $_POST['q'] defined in "highscore.php"
// and then display the data according to the user's input
xhr.addEventListener("load", (event) =>
{
if (xhr.readyState == 4 && xhr.status == 200) { // display data accordingly }
});
xhr.send();
}
and below is a screenshot of the index in the server. "sample.html" is the page for displaying all the data.
However, when inspecting "sample.html", I cannot see the "ajax" folder loaded, nor any other .php files even when I changed the path "ajax/( ).php" to "( ).php". Could anyone explain why this will happen? (In the second screenshot because the parent folder contain my server's name so I covered it)
The browser dev tools (the inspect method you are using) do not list files in your server folder. It only displays files used to load your sample.html page, like CSS, JS files directly referenced (with <script> tags, and so on), etc.
Your .php files might still work, if your javascript ajax method calls them accordingly and they are reachable by the user's browser.
I'm trying to use Cloud Code to check whether a user-submitted image is in a supported file type and not too big.
I know I need to do this verification server-side and I think I should do it with Cloud Code using beforeSave – the doc even has a specific example about data validation, but it doesn't explain how to handle files and I couldn't figure it out.
I've tried the documented method for saving files, ie.
file = fileUploadControl.files[0];
var parseFile = new Parse.File(name, file);
currentUser.set("picture", parseFile);
currentUser.save();
and in the Cloud Code,
Parse.Cloud.beforeSave(Parse.User, (request, response) => { // code here });
But 1. this still actually saves the file on my server, right? I want to check the file size first to avoid saving too many big files...
And 2. Even then, I don't know what to do in the beforeSave callback. It seems I can only access the URL of the saved image (proof that it has been uploaded), and it seems very counter-intuitive to have to do another https request to check the file size and type before deciding whether to proceed with attaching the file to the User object.
(I'm currently using remote-file-size and file-type to check the size and type of the uploaded file, but no success here either).
I also tried calling a Cloud function, but it feels like I'm not doing the right thing, and besides I'm running into the same issues.
I can call a Cloud function and pass a saved ParseFile as a parameter, and then I know how to save it to the User object from the Cloud Code using the masterkey, but as above it still involves uploading the file to the server and then re-fetching it using its URL.
Am I missing anything here?
Is there no way to do something like a beforeSave on Parse.File, and then stop the file from being saved if it doesn't meet certain criteria?
Cheers.
If you have to do something with files, parse lets you overwrite the file adapter to handle file operations.
You can indicate the file adapter to use in your ParseServer instatiation:
var FSStoreAdapter = require('./file_adapter');
var api = new ParseServer({
databaseURI: databaseUri ,
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID,
filesAdapter: fs_store_adapter, // YOUR FILE ADAPTER
masterKey: process.env.MASTER_KEY, //Add your master key here. Keep it secret!
serverURL: "https://yourUrl", // Don't forget to change to https if needed
publicServerURL: "https://yourUrl",
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
}
maxUploadSize: "500mb" //you will now have 500mb limit :)
});
That said, you can also specify a maxUploadSize in your instatiation as you can see in the last line.
you have to use save in background
file = ParseFile("filename", file)
file?.saveInBackground({ e ->
if (e == null) {
} else {
Toast.makeText(applicationContext, "Error: $e", Toast.LENGTH_SHORT).show()
e.printStackTrace()
Log.d("DEBUG", "file " + e.code)
}
}, { percentDone ->
Log.d("DEBUG", "file:" + percentDone!!)
})
I think it might have asked before. But I couldn't find any results based on my search keywords.
In my use case I am configuring endpoints based on stage information [desktop, preprod, prod]. I am using golang for backend. In the backend I use the APP_STAGE environment variable to read the respective configs. For example,
fileName = APP_STAGE + "-endpoints.cfg"
And I export the variable before starting the server.
$export APP_STAGE="desktop"
And desktop-endpoints.cfg will look like this,
{
"featured" : {
"httpendpoint": {
"url": "http://localhost:8081/api/services/featured/"
}
},
"latest" : {
"httpendpoint": {
"url": "http://localhost:8081/api/services/latest/"
}
}
}
But how can I achieve this in client side [javascript]? I have files in the following structure,
app/
view.js
featured.js
home.js
Each of the file uses different endpoints to make ajax calls. How can read the stage config based on some variable [if not env variable] in javascript?
Could someone help me with this? I am fairly new to javascript.
Thanks.
JavaScript files are executed at client side, by the browser. The browser does not have access to the server config files, so it is the server's responsibility to read/get proper config values and make them available to the client.
There are multiple ways to deal with this. I will outline some possible solutions.
1. Include the correct endpoints in the HTML files
You may choose to include the correct endpoints in the HTML files that refer to the javascript files in which they would be used.
The HTML files would be templates and not static files, and you can use the html/template package to execute those templates to include the necessary URLs and everything else you need, and generate the final HTML that will be sent to the clients.
The HTML template may contain a <script> tag initializing certain JavaScript variables, which then can be used from the included JavaScript files.
Here's a simple example passing the featured httpendpoint.
HTML Template ("home.html"):
<html>
<head>
<script>
var featuredHttpEndpoint = "{{.FeaturedHttpEndpoint}}";
</script>
<script src="view.js"></script>
<script src="featured.js"></script>
<script src="home.js"></script>
</head>
<body>Your body</body>
</html>
And the handler that would serve this HTML template:
var homeTempl = template.Must(template.New("").ParseFiles("home.html"))
func homeHandler(w http.ResponseWriter, r *http.Request) {
m := map[string]interface{}{
// Insert the value of endpoint from your config
"FeaturedHttpEndpoint": "http://localhost:8081/api/services/featured/",
}
if err := homeTempl.Execute(w, m); err != nil {
// Handle error
}
}
Mapping the home handler e.g.:
http.HandleFunc("/index.html", homeHandler)
And make sure the home page is not cached, so the browser will always ask for a fresh copy in which your server can insert the actual config values.
2. Perform AJAX requests from the JavaScript files
You may choose to perform AJAX requests from the JavaScript files to query the necessary information. A simple example of this can be found in this question: Dynamically refresh a part of the template when a variable is updated golang
In a real-life example you would transmit all the config values that the client needs with one request (e.g. in JSON format), here I only transmit a single value.
Getting / sending only the featured httpendpoint:
In JavaScript:
var featuredHttpEndpoint = "";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var config = JSON.parse(xhr.responseText);
featuredHttpEndpoint = config.FeaturedHttpEndpoint;
}
}
xhr.open("GET", "/config.json", true);
try {
xhr.send();
} catch (err) {
// handle error
}
And the Go handler providing the config values:
func configHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
m := map[string]interface{}{
// Insert the value of endpoint from your config
"FeaturedHttpEndpoint": "http://localhost:8081/api/services/featured/",
}
if err := json.NewEncoder(w).Encode(m); err != nil {
// Handle error
}
}
Which must be mapped to the path the client calls, e.g.:
http.HandleFunc("/config.json", configHandler)
3. Use Javascript files as templates
You may also choose to make your Javascript files templates, and when serving them, you may use a template engine to include endpoints based on your environment / APP_STAGE. See point #1 as an example to serving templates.
If you're going down this path, you have to take care of properly configuring caching of the Javascript files, as the browser will not ask you again for the js files if their caching info says they are not expired.
Is there a possible way to read a local file in JavaScript.
MyFolder:
db.csv
Parse.js
Trying to fetch the contents of file db.csv in Parse.js, But in vain.
Can you share some links where I can get enough knowledge how to read a file.
Running Instruments in Xcode5, with test scripts in .js file where I have to feed in some values from a .csv file.
iOS UIAutomation, apple provides an api for running a task on the target's host.
performTaskWithPathArgumentsTimeout
Using this, we can have a bash script to printout the contents of a file that we wanted to fetch in the first case.
Bash script can be as simple as this for this requirement.
#! /bin/bash
FILE_NAME="$1"
cat $FILE_NAME
Save it as for example FileReader.sh file.
And in your automation script,
var target = UIATarget.localTarget();
var host = target.host();
var result = host.performTaskWithPathArgumentsTimeout(executablePath,[filePath,fileName], 15);
UIALogger.logDebug("exitCode: " + result.exitCode);
UIALogger.logDebug("stdout: " + result.stdout);
UIALogger.logDebug("stderr: " + result.stderr);
where in,
executablePath is where the command need to be executed.
var executablePath = "/bin/sh";
filePath is the location of the created FileReader.sh file. When executed, outputs the content to standard output (in our requirement).
[give full absolute path of the file]
fileName is the actual file to fetch contents from.
[give full absolute path of the file] In my case I had a Contents.csv file, which I had to read.
and the last parameter is the timeout in seconds.
Hope this helps others, trying to fetch contents (reading files) for performing iOS UIAutomation.
References:
https://stackoverflow.com/a/19016573/344798
https://developer.apple.com/library/iOS/documentation/UIAutomation/Reference/UIAHostClassReference/UIAHost/UIAHost.html
If the file is on the same domain as the site you're in, you'd load it with Ajax. If you're using Ajax, it's be something like
$.get('db.csv', function(csvContent){
//process here
});
Just note that the path to the csv file will be relative to the web page you're in, not the JavaScript file.
If you're not using jQuery, you'd have to manually work with an XmlHttpRequest object to do your Ajax call.
And though your question doesn't (seem to) deal with it, if the file is located on a different domain, then you'd have to use either jsonP or CORS.
And, just in case this is your goal, no, you can't, in client side JavaScript open up some sort of Stream and read in a file. That would be a monstrous security vulnerability.
This is a fairly simple function in Illuminator's host functions library:
function readFromFile(path) {
var result = target.host().performTaskWithPathArgumentsTimeout("/bin/cat", [path], 10);
// be verbose if something didn't go well
if (0 != result.exitCode) {
throw new Error("readFromFile failed: " + result.stderr);
}
return result.stdout;
}
If you are using Illuminator, this is host().readFromFile(path).