NestJS - Get current user from request and validate query params - nestjs

I have a route /users to get user list, the controller method needs to get current user, also needs to validate input query params. So I write like this:
#UseGuards(AuthGuard('jwt'), RolesGuard)
#Roles(UserRole.GLOBAL, UserRole.ORG)
#Get('users')
findAll(#Request() req, #Query() query: FindAllUsersDto) {
//code here.
}
This works. I am wondering if this is a little duplication. Because I can use req.query to get query object. But if I don't write #Query() query: FindAllUsersDto, the validation pipe won't work. So is my code meaningful or is there a more simple way? Thanks.

Related

ExpressJS - switching between multiple categories in API requests

I'm currently fetching below API from http://localhost:3009/api/get-products/ .
How do I switch between 10 categories and search using other keywords ?
app.get("/api/get-products",async (req, res) => {
client.execute('affiliate.product.query', {
'app_signature':'mcc',
'category_ids':'111,222,333', <--- query different categories
'keywords':'shirt', <--- query different search keyword
'target_currency':'USD',
'target_language':'EN',
}
You should use query parameters that allow you to specify what keywords or categories you want to receive:
Look at that example:
https://example.com/over/there?name=ferret.
While passing a query like that, you are able to get name from req object.
Here you can find more about the query parameters in Node.js: How to get GET (query string) variables in Express.js on Node.js?

mongoose - select specific fields in Model.create

const generatedEvent = await Event.create(req.body);
res.send(generatedEvent);
I am getting some data from the request body and I can generate a new Event. And I'm returning the event to client when it has generated. But I don't want to return all fields with event. I want to make filter operation like how we are using select function like this: Event.find().select({title:1,description:1})
How can i use this select func with Model.create?
If you take a look at the mongoose-source code, you can see that Model.create returns a promise with the created/inserted documents. There's no way to specify a filtering-options to return only specific fields.
Of course you could do a .find() in combination with a .select() call after creating/inserting a new record but that would result in one extra DB-query for each insert which does not make a lot of sense.
You could instead just return the desired properties from the returned document, since you know that a new document was inserted successfully with the provided data, when the promise resolved. So you could simply do:
res.send({title: generatedEvent.title, description: generatedEvent.description});
Model.create() internally doesn't fetch the document from the database, rather it actually returns the result whether it's inserted successfully or not. If successful, mongoose will return the original mongoose document that mongoose created before sending to the database.
So you could just select the fields by yourself. Using es2015 Object destructuring assignment and Object shorthand property names would help writing more concise code.
const { title, description } = await Event.create(req.body); // Object destructuring
res.send({ title, description }); // Object shorthand property names

Express, Mongoose, db.findOne always returns same document

I am attempting a CRUD app with MEAN stack. I am using mongoose in Express to call to the MongoDB. I am using the FindOne function with a specified parameter, and it's always returning the same (incorrect) document.
I know I am connected to the correct database, since I get a document back from that collection, but it's always the same document, no matter what I pass as the parameter.
module.exports = mongoose.model('Player', playersSchema, 'players'); //in player.js
const Player = require('./model/players');
app.get('/api/player/:id', (req, res) =>{
Player.findOne({id: req.params.playerId},
function(err, player) {
if(err) {
res.json(err);
}
else {
res.json(player);
}
});
});
I have 3 separate "players", with three distinct "playerID" fields (38187361, 35167321, 95821442). I can use Postman to GET the following URL, for example:
http://localhost:3000/api/player/anythingyouWantInHere
and it will return 38187361, the first document. I've been over this website, many tutorials, and the Mongoose documentation and I can't see what I'm doing wrong..
I'd like to eventually find by playerId OR username OR email, but one hurdle at a time...
From the mongoose documentation of findOne, if you pass Id a null or an empty value, it will query db.players.findOne({}) internally which will return first document of the collection everytime you fetch. So make sure you are passing non-empty id here.
Note: conditions is optional, and if conditions is null or undefined,
mongoose will send an empty findOne command to MongoDB, which will
return an arbitrary document. If you're querying by _id, use
findById() instead.
Your route is '/api/player/:id', so the key on the req.params object will be 'id' not 'playerId'.
I don't know what/where/if you're populating the playerId param, but if you update your query to call req.params.id it should actually change the document based on the path as you seem to be wanting to do.
I had the same problem, and it was that the name of column's table was different from the model I had created.
In my model the name of the wrong column was "role" and in my table it was "rol".

CloudantDB: using db.get without id

I have a table:
id: 001
name: test
provider_id:ABC123
and I try to query with provider_id and get a error message, but not with id:001
db.get("ABC123", function(err, data) {
// The rest of your code goes here. For example:
console.log("Found id:", data);
});
Please give me your thoughts how to run successfully db.get + provider_id
You can't use db.get without the ID. However you can use either Query or Views to find the document you are looking for.
With query you can use a selector such as {"provider_id":"ABC123"} to find the documents which contain that provider id.
With views you can use the provider_id as the key and the doc id or null as the value, such as:
function (doc) {
emit(doc.provider_id, doc._id);
}
If you are using null as the value, you should use the include_docs=true option for the request. See your library's documentation on how to use views and query.

Sequelize - always return arrays even when only one record is retrieved

I'm using Sequelize with Postgres and Angular.js in the front-end.
I'm setting up some routes to expect arrays in the response:
'getData': {
method: 'GET',
// isArray: true,
url: 'stuff/:id',
params: {id: '#id'}
}
However, when only one record is retrieved Sequelize seems to return an object directly
rather than an array with one object in it, which breaks the resource:
Error in resource configuration. Expected response to contain an array but got an object
Is there a way of setting up Sequelize to always return arrays even if there's only one record retrieved?
Or, a clean way of wrapping the data when it gets to ng-resource?
Thanks!
Angular should support object responses, but in any case:
Model.find() will return an object, Model.findAll() will return an array. You can just swap to using a findAll, if filtering on primary key it won't make much of a difference.
Model.find() also takes query parameters as it's second parameter so you should also be able to do Model.find({where: ..}, {plain: false}) but that hasn't been tested and isn't exactly public API.

Resources