I have successfully implemented serving static files using res.sendFile() but it doesn't works if I add some querystring.
E.g. the below code works absolutely fine.
res.sendFile(path.join(__dirname, '../public', '/index.html'));
But if I do this, it fails
res.sendFile(path.join(__dirname, '../public', '/index.html?id=' + req.params.id));
res.sendFile(path.join(__dirname, '../public', '/index.html?id=123'));
Then I get the below error
ENOENT, stat '/Users/krishnandu/Documents/Project/public/index.html?id=123'
404
Error: ENOENT, stat '/Users/krishnandu/Documents/Project/public/index.html?id=123'
at Error (native)
You cannot pass query string parameters with res.sendFile(). You have to specify the file path as the 1st parameter in res.sendFile()
Syntax is :
res.sendFile(path [, options] [, fn])
So what you can do is,
Use the query string with a route, say route1 (refer the below code)
Inside the GET method of route1, use res.sendFile()
app.get('/route1',function(req,res){
res.sendFile(path.join(__dirname, '../public', '/index.html'));
});
res.redirect('/route1?id=123');
See also Express API documentation of res.sendFile and res.redirect.
This answer is to further add on to #Marie Sajan's answer by covering the question asked by #Sky in a comment.
To access id in index.html after using #Marie Sajan's answer you can use normal client-side javascript. You could do something like this in <script> tags in your html file:
var query = location.href.split("?")[1];
This would get you a string such as "id=123&name=ted".
From here you can use javascript to get the value of id. The full code might look something like this:
var query = location.href.split("?")[1]; //A string of all parameters in the URL
var params = query.split("&"); //Turns the string into an array of parameters
var id; //To store the value of id
params.forEach((param, index) => {
//This checks each key-value pair, in the format key=value, for the specific id key we want
var key = param.split("=")[0]; //In id=123, this would be "id"
var value = param.split("=")[1]; //In id=123, this would be "123" (as a String)
if (key == "id") id = value;
});
Now the javascript variable id will contain the value "123".
If you were also looking for the values of more query parameters in addition to the id key, you would simply add more if statements inside the forEach to check for those specific keys.
In a link such as "http://google.com/?q=stack+overflow&id=123", this code would be able to get the value "123" of id when implemented as client-side javascript either directly in the HTML file in <script> tags, or in a separate client-side js file that is used by the HTML file. Note that #Marie Sajan's answer is entirely server-side code, while this code is what would be used on the client-side.
This answer does not address the original question, it only adds further useful content to an accepted answer to the question based on the needs of viewers of this page.
Related
I was using OMDBapi to get the details of different movies. I successfully fetched the result and it returns a json object like this;
{"Title":"WWA: The Inception","Year":"2001","Rated":"N/A","Released":"26 Oct 2001","Runtime":"N/A","Genre":"Action, Sport","Director":"N/A","Writer":"Jeremy Borash","Actors":"Bret Hart, Jeff Jarrett, Brian James, David Heath","Plot":"N/A","Language":"English","Country":"Australia","Awards":"N/A","Poster":"https://m.media-amazon.com/images/M/MV5BNTEyNGJjMTMtZjZhZC00ODFkLWIyYzktN2JjMTcwMmY5MDJlXkEyXkFqcGdeQXVyNDkwMzY5NjQ#._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"6.0/10"}],"Metascore":"N/A","imdbRating":"6.0","imdbVotes":"22","imdbID":"tt0311992","Type":"movie","DVD":"N/A","BoxOffice":"N/A","Production":"N/A","Website":"N/A","Response":"True"}
Note that we get this type of object from the api if we want to get a particular movie details and that is what i was doing. Now to show the different details to a user, i started parsing this JSON object which works fine but when i try to get the value of the Value key present inside the Ratings key, it returns undefined.
I am working with react-native. After getting the data, i stored it inside the state, named it as details. Then to get it;
this.state.details.Title //if i wanted to get the Title and it works fine.
Then for Value inside Ratings;
this.state.details.Ratings[0].Value
But it returns undefined.
Also note that this works fine in pure Javascript as i parsed the dict in the browser console in the same way and it returned the correct value.
Here is more code;
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
const response = await fetch(`http://www.omdbapi.com/?i=${this.props.navigation.getParam('i')}&apikey=******`) // where this.props.navigation.getParam('i') is the omdbid of the movie
const result = await response.json()
this.setState({details: result})
}
Here is error log;
undefined is not an object (evaluating 'this.state.details.Ratings[0]')
You're most likely trying to access state object before fetch has done it's job .... it's an async op ... so you should make sure your data is ready before rendering...
if (this.state.details) {
// start rendering...
}
More Explanation
your setState function should be executed right after fetch has finished its job, and since it's an async operation, it's going to take some time ...During that time, render function is executed with no state.details --> causing your issue ...
That's why you should check for state before rendering ... besides, the optional chaining trick Silversky Technology mentioned in his answer
If the value property you are accessing from the object might be not available for all the movies in the data you are getting from API response so it might cause you to error when accessing key from undefined objects.
To overcome the issue there is a way, you can try a fix as below:
this.state.details.Ratings[0]?.Value
The ? symbol lets the javascript not give an error when the value key not available in the object. it will make the accessing of property optional.
When storing objects in states it often causes problems as you are doing in line
this.setState({details: result})
Save result after strigifying it like
JSON.stringify(result)
this.setState({details: result})
Then when fetching form state, parse it back to object by
var result = JSON.parse(this.state.details)
Then you should be able to access it
You can access Ratings[0].Value by
this.state.details.Ratings && this.state.details.Ratings[0].Value
like,
<Text> {this.state.details.Ratings && this.state.details.Ratings[0].Value} </Text>
Hi I want to get a custom JSON file from the stormpath API in a normal JS function instead of within a view.
The view method is like this:
var stormpath = require('express-stormpath');
app.get('/email', stormpath.loginRequired, function(req, res) {
res.send('Your email address is:', res.locals.user);
});
However when I attempt to just use the method like this:
var customD = res.send('Your email address is:', res.locals.user);
it returns an unexpected token ' ( ' error
In the posted example the quotation marks ’ are a rich encoded, not the standard single ' or double quotes ". I would replace your quotes with single quotes. What text editor are you using to write your node application?
Regarding the original question about custom data, can you show us how you are assigning the custom data properties? I suspect that you might have run into this issue: https://github.com/stormpath/stormpath-sdk-node/issues/88
Can you try the following code sample?
var stormpath = require('express-stormpath');
app.get('/email', stormpath.loginRequired, function(req, res) {
res.send('Your email address is:' + res.locals.user.email);
});
I suspect a few things:
Your code is running OUTSIDE of a route.
You have a comma in res.send(), so the send method thinks you're passing in additional arguments as opposed to a single string.
You're not using the email address directly.
I would like to get the response of a website that has results posted by a form. I've tried using WebClient, WebRequests, etc.
Current Code:
using (var client = new WebClient())
{
var buffer = client.UploadValues("https://secure.monroecc.edu/pls/bpr1/bwzkfcls.P_GetCrse", "POST", vals);
return Encoding.UTF8.GetString(buffer, 0, buffer.Count());
}
Also pretty sure that the current code isn't wrong it's just missing something. When I do get the response of the website it's wrong, it's the page where you would fill out the form.
If you try to GET the website it results in this error on the website itself (without posting the variables that go along with it):
VARIABLES IN FORM NOT IN PROCEDURE:
NON-DEFAULT VARIABLES IN PROCEDURE NOT IN FORM: TERM_IN,SEL_SUBJ,SEL_CRSE,SEL_TITLE,BEGIN_HH,BEGIN_MI,BEGIN_AP,SEL_DAY,SEL_PTRM,END_HH,END_MI,END_AP,SEL_CAMP,SEL_SCHD,SEL_SESS,SEL_INSTR,SEL_ATTR,SEL_LEVL,SEL_INSM
DAD name: bpr1
PROCEDURE : bwzkfcls.P_GetCrse
URL : http://secure.monroecc.edu:63500/pls/bpr1/bwzkfcls.P_GetCrse
PARAMETERS :
===========
Here's an image of the request being sent. (Viewing using Chrome)
I know that the website usses oracle PLSQL but again that doesn't seem to help me with retrieving the results of the search.
I posted the form using the following code:
private void Run(string[] args)
{
NameValueCollection vals = new NameValueCollection();
vals.Add("TERM_IN", "");
vals.Add("SEL_SUBJ", "");
vals.Add("SEL_CRSE", "");
vals.Add("SEL_TITLE", "");
vals.Add("BEGIN_HH", "");
vals.Add("BEGIN_MI", "");
vals.Add("BEGIN_AP", "");
vals.Add("SEL_DAY", "");
vals.Add("SEL_PTRM", "");
vals.Add("END_HH", "");
vals.Add("END_MI", "");
vals.Add("END_AP", "");
vals.Add("SEL_CAMP", "");
vals.Add("SEL_SCHD", "");
vals.Add("SEL_SESS", "");
vals.Add("SEL_INSTR", "");
vals.Add("SEL_ATTR", "");
vals.Add("SEL_LEVL", "");
vals.Add("SEL_INSM", "");
using (var client = new WebClient())
{
var buffer = client.UploadValues("https://secure.monroecc.edu/pls/bpr1/bwzkfcls.P_GetCrse", "POST", vals);
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, buffer.Count()));
//Console.Read();
}
}
It returns a 200 status code and valid html indicating that the form was received properly. However, since none of the values are correct the returned page says that there is a missing form element that must be included (NAME NOT FOUND FOR PIDM: )
The parameter mismatch error you are receiving means that the parameters you are passing in are not the ones that the stored procedure expects. You'll need to get an exact list of the parameters and expected values first, then you can just plug them in and this should work. Unfortunately the page returns a 200 status code so you'll have to parse out somehow whether there was an error or not.
Use a GET request instead of a POST.
You are asking for a page that follows a form to give you a result set when it never actually receives the form variables that would make the result possible.
Your variable vals which should pass the set of variables never does.
VARIABLES IN FORM NOT IN PROCEDURE:
NON-DEFAULT VARIABLES IN PROCEDURE NOT IN FORM: TERM_IN,SEL_SUBJ,SEL_CRSE,SEL_TITLE,BEGIN_HH,BEGIN_MI,BEGIN_AP,SEL_DAY,SEL_PTRM,END_HH,END_MI,END_AP,SEL_CAMP,SEL_SCHD,SEL_SESS,SEL_INSTR,SEL_ATTR,SEL_LEVL,SEL_INSM
This response error says that it never received any of the variables listed. I would trace back in your code to the location were you name and assigned your list of variables to the Collection vals. Check for proper spellings and proper assignment.
I was able to use the code in this answer to access a value in a JSON string posted to the server.
If the server gets {"MyKey":"My Value"} then the value for "MyKey" can be accessed with request.body.MyKey.
But the JSON strings that get sent to my server look like this:
[{"id":"1","name":"Aaa"},{"id":"2","name":"Bbb"}]
I could not find a way to access anything in that. How do you do it?
request.body is a standard JavaScript object and in your case a vanilla JavaScript array. You would just handle request.body like you would any JavaScript Array object. e.g.
app.post('/', function(request, response){
var users = request.body;
console.log(users.length); // the length of the array
var firstUser = users[0]; // access first element in array
console.log(firstUser.name); // log the name
users.forEach(function(item) { console.log(item) }); // iterate the array logging each item
...
Problem:
According to the author, jsTree Documentation:
When opening a closed node (that has no loaded children) an AJAX request is made.
How do I configure jsTree to get rid of these AJAX data requests made for each empty/childless node? I want my empty nodes remain empty (or childless)!
Given (simplified):
JSON data container (data.json)
{
"data" : "Root node with no children",
"children" : []
}
jsTree configuration
{
"json_data" : {
"ajax" : {
"url" : "data.json",
"type" : "GET",
"dataType" : "json",
"dataFilter" : function (data, type) {
//some filtering function
}
}
},
"plugin" : ["json_data"]
}
Mark the state of the leaf node as "leaf". That should fix it.
I have had this problem setting the attribute state="closed" on childless nodes for XML trees. Removing the state attribute solves the issue.
I had a similar problem a couple of weeks ago. I had a function call in the "url" field, which ultimately led to java code that made a JSON string based on a SQL query. So when I clicked on a childless closed node, the function was called again, resulting in an endless tree.
the way I solved this was:
"json_data" : {
"ajax" : {
"url" : "getAreaTree?treeType=Areas&ownerPhone=<%=webSessionObject.getUserPhoneNum()%>",
"data" : function (n) {
return { id : n.attr ? n.attr("id") : 0 };
}
}
},
The result of the function defined in "data" will be added as a parameter to the "url" function. Then I can check whether the parameter was 0 (initial load) or 1 (the id of my root) or something else.
If this doesn't work for you, maybe you could try something like this:
.bind("before.jstree",function(event,data){
if(data.func === "create"){
var foo = true;
data.inst._get_node(null, true).each(function () {
if(this.id!=rootId && this.id!=0){
foo = false;
})
if(!foo){
event.stopImmediatePropagation();
return false;
}
}
})
I'm not exactly sure this works though. "before.jstree" fires before all events. I'm checking whether the function about to fire is "create", and if it is I check the id of the selected node. If it's something else than my root's id or 0 (initial load) I stop the create function.
I use a similar structure for a different situation, so something like this should work. It could be that the "create" event is not what you should be binding to though. You can change it to
.bind("before.jstree",function(event,data){
console.log(data.func)
if(data.func === "create"){
To see which functions are called.
Just skip the children attribute. Obviously your node has no children, but you specify the attribute? Simply skip it, the node will be rendered as a leaf node and no further requests will be made.
I've been struggling with this problem too. I got the main idea from jsTree - loading subnodes via ajax on demand
The basic problem is that when we click a child node that is not set to leaf, a new AJAX request is generated with the URL we set in the tree configuration. The trick seen in the above link is to provide a function instead of a static URL string. My jstree is used to display a directory structure on the server, so I can arrange to dynamically add to the URL for sub-directories. If you assign a function to the url property of the ajax property in your jstree configuration, the function receives the node you clicked as an argument. My nodes display the names of directories or files so I can use the text() function to get the raw directory name. There seems to be some space in front of the name returned in this way, so I used a String trim() function and then encodeURIComponent to give me something I can use in a URL.
If -1 is passed to the url function, then you're at the root and you can safely use your base URL. Now, this only works for the first level of the hierarchy. I've got a bit more work to do, adding the full path to the metadata of the node or something like that, but this idea might put you on the right track. It looks as if it's not exactly a bug but by design. You have to make sure a request triggered by a subnode sends a suitable URL to the server.
Here's the url property I've assigned to the ajax object in my jstree configuration:
"url": function (node) {
var subDirectory = "",
url = "";
if (node === -1)
{
url = "/tree_service/tree/format/json?path=exercises";
}
else
{
subDirectory = encodeURIComponent(node.text().trim());
url = "/tree_service/tree/format/json?path=exercises/" + subDirectory;
}
return url;
}
My plan is to build the URL cumulatively by polling the node for its full path, then adding the node's name as above to create the final URL. Pseudo code:
//haven't figured out how to add the path to the node and then retrieve it
path = node.metadata.path;
path = encodeURIComponent(path);
subDirectory = encodeURIComponent(node.text().trim());
url = path + "/" + subDirectory;
UPDATE
See my answer here how to get the metadata of jsTree. about getting the metadata from the node using node.data().path