Add multiple values to the URL dynamically - javascript

I am trying to make a request to an endpoint that expects only one user account Id, so I tried to separate the user account Ids (if they are multiple) by &. The this.account is an array with account Id strings. And this is how I am doing it but it still appends the values with a comma:
getAccountStats(callback) {
let acc = this.account.map((val) => {
if (val>1) {
return 'accountID_'+val+'&'
}
return 'accountID__'+val;
})
let url = `/${acc}/userAccount`;
axios.get(url, callback);
}
When I console.log the url, it returns /accountID_1,accountID_2/userAccount but I want it to be /accountID_1&accountID_2/userAccount. Any idea how to achieve this. TIA

I am trying to make a request to an endpoint that expects only one user account Id, so I tried to separate the user account Ids (if they are multiple) by &
The short answer is what you think you want won't ever work. If the endpoint only expects 1 account id, then trying to add more won't do what you want.
but I want it to be /accountID_1&accountID_2/userAccount
This doesn't look like a valid endpoint. So I doubt you really want this.

Related

Access the last document relationing it with an user

In my app users send a form to the server, I'm retrieving the last one sent in the next way:
const property = set[set?.length -1 ]
But I would like to retrieve not the last form sent in general but the last one sent by the user using the app. I was trying with:
if (user._id === set?.owner)
But if the userID isn't the same that the one who sent the last form it won't return anything and without the condition it just show the last form sent independently of the user accesing it.
Filter the array to find possible valid matches first.
const setByUser = set.filter(form => form.owner === user._id);
Then get whichever one you want from that array.

GET or POST request => very long URL

I'm creating a dynamic query in postgresql to filter a resultset.
I pass the parameters in the URL, an example is:
http://www.myurl.com/search?query=hello+word&sortorder=relevance&date=week&categories=cat1,cat2
The problem is, when a user selects a lot of categories (and other parameters that aren't included in the example URL), the URL will be very, very long. I'm using UUIDv4 for ID's so a lot of UUIDv4's are in the URL, separated by comma's.
Is it a better idea to do this with a POST request?
EDIT:
I'm using validator to check if the incoming parameters are valid UUIDv4 (or numbers, ... whatever I need for that parameter to be).
I'm using node-postgres to execute queries. This supports prepared statements, but I have NO CLUE how to use prepared statements with dynamic queries.
My SELECT code now looks like this (simplified):
const { featured, order } = req.body;
// featured
let featuredQuery = '';
if (featured !== undefined && validator.isBoolean(featured.toString())) {
let featuredQuery = ` AND featured = ${featured}`;
}
// order
let orderQuery = 'timestamp DESC';
if (order !== undefined) {
switch (order) {
default:
case 'date':
orderQuery = 'timestamp DESC';
break;
case 'user_id':
orderQuery = 'user_id DESC';
break;
}
}
const query = `
SELECT
name,
description
FROM
users
WHERE
active = true
${featuredQuery}
ORDER BY
${orderQuery}
`;
As you can see, I'm not passing prepared statements ($1, $2, ...) to the query but I'm using template literals. I have NO CLUE how to use prepared statements to add/delete where clauses.
Is there a safer way to do this?
EDIT 2: parameters are not containing sensitive information. I pass the user ID in the authorization header as a JWT.
If you're fetching the contents of your parameter-laden URL using a program, not a browser, long GET URLs don't matter very much. (In browsers they're ugly.) For best results, and less testing burden on various legacy proxy servers etc, do your best to keep your URL length to 2000 octets or less. (Payload size for POST requests has no such limitation.)
Beware that URLs get logged. So, if your parameters carry any sensitive information you should consider using POST rather than GET. Otherwise your users' sensitive information will land in your web server logs, presenting a juicy target for cybercreeps.
And, please please read up on SQL injection. Please please sanitize your incoming parameters before handing them off to your database server. Remember that cybercreeps can (and will) hit your URL from their malicious programs and try all sorts of combinations trying to break in.

Using ExpressJS, how do I extract different data from a SQLite table using the URL?

I want to access resources from a SQLite database table. I have one table for accounts, one for movies and one for reviews. The reviews-table is constructed like this:
CREATE TABLE IF NOT EXISTS reviews (
id INTEGER PRIMARY KEY,
authorId INTEGER,
movieId INTEGER,
review TEXT,
rating INTEGER,
FOREIGN KEY('authorId') REFERENCES 'accounts'('id'),
FOREIGN KEY('movieId') REFERENCES 'movies'('id')
)
What I want to do is that I want to be able to get all reviews, made by one author. But I also want to be able to get all reviews, made for the same movie. Below is my code for getting all reviews made by the same user/author. The code looks the same when getting the reviews based on the movie, with a few changes.
Both of them does what I want them to do. But of course only the one written first in the file are running.
const authorId = request.params.authorId;
const query = "SELECT * FROM reviews WHERE authorId = ?";
const values = [authorId];
db.all(query, values, function (error, review) {
if (error) {
response.status(500).end();
} else if (!review) {
response.status(404).end();
} else {
response.status(200).json(review);
}
});
});
The url will look the same no matter which of them I want running; http://localhost:3000/reviews/3. How can I differentiate the url so that they know which one should run?
I have tried to experiment with query strings, but I'm not sure how that works, and after hours of searching for something that worked on my code, I gave up.
I have also been thinking about using something like
app.use(function (request, response, next) {
if (request.method == "GET" && request.uri == "/reviews/:authorId") {
response.send("Hello World");
} else {
next;
}
});
This didn't work, and it didn't work if I tried to remove ":authorId" from the url either. The page just keeps loading.
So how do I solve this?
The most dynamic would be a single route /reviews and use the query string with the params like ?author=123 or ?movie=123, they can be combined like ?author=123&movie=123. As you want to return JSON the code will be used via API, so the pretty path is usually not as important as when it is a web-url. To make the implementation effective, most people use a function where you can drop the query object in and get the where-clause, or use an ORM.
In express, when you have routers like '/reviews/:authorId' and then '/reviews/:movieId', then the second one will never be called, because the first one will always match. That is something to be careful about when organizing your express routes.

Using a variable in a WHERE clause MySQL/Node

I'm trying to make a MySQL query to filter data from a table. Effectively what I want to do is:
SELECT data FROM table WHERE column IN ?
The filter is coming from checkboxes in a form on a webpage, so I can pass an array or object fairly easily, but it'll be a varying number of parameters for the IN each time, so I can't us multiple ?. I tried making a for loop to make multiple queries concatenate the arrays that the queries returned, but I ran into scope issues with that. I also tried passing an array directly to the query, but that throws a syntax error. I'm sure there's a straightforward answer to this but I'm not sure how to do it.
Edit: source code added:
Here's where I'm at:
const filterShowQuery = `SELECT sl_Show.showId, sl_Band.BandName,
sl_Show.date, sl_Venue.venueName,
sl_Show.length, sl_Show.attendance, sl_Show.encore FROM sl_Show
JOIN sl_Band on sl_Show.BandID = sl_Band.BandId
JOIN sl_Venue on sl_Show.VenueId = sl_Venue.VenueId
WHERE sl_Band.BandName IN (?)
ORDER BY sl_Band.BandName;`;
Trying to get an array into the ? in WHERE sl_Band.BandName IN
const getShows = (req, res,next) =>{
var {bands, venues} = req.body;
var i = 0; //left over from previous attempt
var data = [];
for (b in bands){
mysql.pool.query(filterShowQuery, bands[b], (err, result) => {
if(err){
console.log('filter band error');
next(err);
return;
}
data = data.concat(result);
console.log(data); //data concatenates property and increases through for loop
})
// same action to be performed with venues once solved
// for (v in venues){
// conditions[i] = venues[v];
// i++;
console.log(data); //data is empty when logging from here or using in res
res.json({rows:data});
}
}
SECURITY WARNING!
I must to say: NEVER, NEVER PASS DATA DIRECTLY TO YOUR SQL!
If you don't know why, just google for SQL Injection. There are lots of examples on how it is done, how easily it can be done, and how to protect your application from this sort of attack.
You should always parametrize your queries. But in the very rare case which you really need to insert data concatenating a string into your sql, validate it before.
(E.g.) If it's a number, than use a Regex or some helper method to check if the value you are inserting into your SQL String is really and only a number and nothing else.
But aside that, you did not provide any source code, so it's really hard to give any help before you do that.

How to query orchestrate.io

I was searching for an easy and simple database for a little highscore system for a some games I'm developing in javascript.
I saw Orchestrate.io in github's student developer pack. I found a suitable drivermodule nodejs orchestrate and have integrated them.
The problem comes with querying orchestrate for my data. I have managed saving scores and querying them with db.list('collection'), but this seems to not responding with all data. It appered to me that some values are not returned.
I read about the db.search('collection','query') function. But I don't really understand how I could return all data because I don't want to query in a specific way.
My objects are as simple as follows:
{"name":"Jack","score":1337}
As I understand, one has to send a key, when putting such values to an orchestrate-collection. But I'd like to query the whole collection and get the values in a descendant order in regard to the score.
As for now I end up sorting the result on the client-side.
I hope you guys can give me some hints for a query that can sort for specific values!
You have the option to use a SearchBuilder
db.newSearchBuilder() //Build a search object
.collection('collection') //Set the collection to be searched
.sort(score, 'desc') //Set the order of the results
.query("*") //Empty search
.then(function (res) { //Callback function for results
//Do something with the results
})
Source
By default, .list uses a pagination limit of 10. You can either increase that, e.g.:
db.list('collection', { limit: 100 })
Or use .links, .links.next (from the docs):
db.list('collection', { limit: 10 })
.then(function (page1) {
// Got First Page
if (page1.links && page1.links.next) {
page1.links.next.get().then(function (page2) {
// Got Second Page
})
}
})

Categories

Resources