router.get(), use only part of url? - node.js

Currently I have this code:
router.get('/admins', function(res,req) {
However, I want it to be when someone goes to say, 'localhost:5000/admins/54323', I want the node-js app to notice 'hey, they're requesting for an admins list! lets find it'. However, with the router.get() function it only works if it is exactly that, is there a way to have it so if only the start is /admins then it sets a variable for the final part?

Through more research, I found an answer. I just put /:id after the /admins bit,
you can access the rest of the string in req.params.id where .id is the same as the string written after the : sign

Related

Adding integers with the eval function is returning an error. (Nodejs)

Please don't ask me not to use eval, this isn't going to be public anyways.
I've made a chatting website, and I have implemented a "!eval" command (admin only), whatever is after it is run. I can use "!eval '2'+'2'" (Strings added), but not "!eval 2+2." The error returned is .
I've console.logged the input to the eval, and it returned exactly what I wanted: "1+1." I've looked around for this, but it seems like no one else had this problem before. A solution (more like a debugging one) is that I tried "eval('1+1')" and returned the same error. Any thoughts? Thanks in advance.
(I forgot to add what I was expecting)
I was expecting this.
VLAZ pointed out in the comments that it must be another piece of code, which he is correct. I was encrypting the messages so it can be sent securely to the client, and it only takes a string. I added
if (typeof(results) != 'string'){
results = String(results)
}
and it seemed to work, Thanks!

Triggering Google Cloud function using console

I am trying to use the google cloud console to test a cloud function. Below is a snippet.
exports.requestCreated = functions.firestore
.document('users/{userId}/requests/{requestId}')
.onWrite((change, context) => {
// execute operation
});
I have tried all sorts of combination of JSON data. E.g.
{"userId":"Xl86pqOpF9T2MAn12p24OJAfYJW2","requestId":"abc1234"}
But I keep getting the following statement in logs:
Request created by {userId}
The actual userId is not being read from the JSON data in the console. Can you help?
This is not a problem with the execution of the cloud function. It's a problem with hardcoding the string.
'users/{userId}/requests/{requestId}' is a hardcoded string. Node.js will not automatically replace {userId} with the value of the variable userId.
Following this previous SO post, try something like this using template strings:
`users/${userId}/requests/${requestId}`
Please note it is surrounded by backticks (`), not single quotes (').
This assumes you already have a userId and requestId variables defined. You must restructure your cloud function like this to retrieve that data. Notice that the specific variable values must be extracted from the event variable.
Thank you, Nareddyt. The function is for Firestore, and the way it is written right now checks if a new document is created under the collection requests. I tried replacing the string as you suggested, but as you pointed out, it requires these variables to be defined. I do not quite understand how to restructure the cloud function because the syntax I have used is how event detection is suggested in the Firestore documentation. My function currently works in its entirety, but testing it is a major pain. I have to go through my mobile app and do the whole userflow to test this function. I am new to Node.js and any guidance would be appreciated.

expressjs pattern to match the rest of the path

I'm trying to create an endpoint that contains an actual path that I extract and use as a parameter. For instance, in the following path:
/myapi/function/this/is/the/path
I want to match "/myapi/function/" to my function, and pass the parameter "this/is/the/path" as the parameter to that function.
If I try this it obviously doesn't work because it only matches the first element of the path:
app.get("/myapi/function/:mypath")
If I try this it works, but it doesn't show up in req.params, I instead have to parse req.path which is messy because the logic has to know about the whole path, not just the parameter:
app.get("/myapi/function/*")
In addition, the use of wildcard routing seems to be discouraged as bad practice. I'm not sure I understand what alternative the linked article is trying to suggest, and I'm not using the query as part of a database call nor am I uploading any information.
What's the proper way to do this?
You can use wildcard
app.get("/myapi/function/*")
And then get your path
req.params[0]
// Example
//
// For the route "/myapi/function/this/is/my/path"
// You will get output "this/is/my/path"

Discord <#!userid> vs <#userid>

so I'm creating a bot using Node.JS / Discord.JS and I have a question.
On some servers, when you mention a user, it returns in the console as <#!userid> and on other it returns as <#userid>.
My bot has a simple points / level system, and it saves in a JSON file as <#!userid>, so on some servers when trying to look at a users points by mentioning them will work, and on others it won't.
Does anyone have any idea how to fix this? I've tried to find an answer many times, and I don't want to have it save twice, once as <#!userid> and then <#userid>. If this is the only way to fix it then I understand.
Thanks for your help!
The exclamation mark in the <#!userID> means they have a nickname set in that server. Using it without the exclamation mark is more reliable as it works anywhere. Furthermore, you should save users with their id, not the whole mention (the "<#userid>"). Parse out the extra symbols using regex.
var user = "<#!123456789>" //Just assuming that's their user id.
var userID = user.replace(/[<#!>]/g, '');
Which would give us 123456789. Their user id. Of course, you can easily obtain the user object (you most likely would to get their username) in two ways, if they're in the server where you're using the command, you can just
var member = message.guild.member(userID);
OR if they're not in the server and you still want to access their user object, then;
client.fetchUser(userID)
.then(user => {
//Do some stuff with the user object.
}, rejection => {
//Handle the error in case one happens (that is, it could not find the user.)
});
You can ALSO simply access the member object directly from the tag (if they tagged them in the message).
var member = message.mentions.members.first();
And just like that, without any regex, you can get the full member object and save their id.
var memberID = member.id;

get method with colon and question mark in server path

Follow up question: What is the code "res.json(false);" doing? Doesn't that print out false on the page instead of showing the data I want?
I'm looking at the following sample code. I understand that .get( is the method and /:characters? is the server path. In this search, what is the point of the colon and the question mark in the path? Shouldn't the question mark come before characters because it is a query?
app.get('/:characters?', function (req, res) {
var chosen = req.params.characters;
if (chosen) {
console.log(chosen);
for (var i = 0; i < characters.length; i++) {
if (chosen === characters[i].routeName) {
res.json(characters[i]);
return;
}
}
res.json(false);
} else {
res.json(characters);
}
});
In this case the question mark signifies an optional parameter "characters". This allows for an endpoint that MAY have a value or not. They are then testing against that parameter to see if it was included. If so they will iterate through the "characters" object and return any matching entry to the endpoint the user specified.
Simplest answer:
:XXX means that its a URL parameter. (i.e. req.params.XXX will pick up what the XXX is)
? means that the parameter is optional. (i.e. the client-side user doesn't need to include this parameter in the url).
So:
/:characters? would allow for: both / AND /yoda to hit this route.
:characters isn't actually part of the query string. It will be part of the url.
The url will be something similar to the following (assuming you are running this server locally and on port 8080):
http://localhost:8080/abcdefg
And in that case, req.params.characters will be 'abcdefg'
Putting an explicit question mark in the route definition is a mistake, in my opinion. I'm not entirely sure what purpose that question mark would serve.
For the follow up question, what it appears to be doing is looking for a match in the characters variable (which I assume is defined externally) by characters[i].routeName, and returning the found value. If no value is found, that's when it sends back false (or tries to - to be honest, I'm not sure what express will do if you try using res.json(false), since I'm not sure false is valid JSON).
This is a normal case that a endpoint or a resource can contain a variable that means
lets take facebook for example so if you see the timeline of MarkZukerberg then the endpoint or url is
https://www.facebook.com/zuck
if you see your own profile then that zuck will be replaced by your name. so the name parameter here is a variable.
When ever a variable is a part of the url then we precede that with a colon sign in express syntax
and if we want to send some other values as the query parameter then we use ? mark to tell the server that the following string will be a query parameter
?name=value&age=12&gender=male
And
res.json(false)
will just return false as the response nothing else

Resources