Loopback 4: Filter option - node.js

Loopback 4 allows to use an automatic/default filter that is really helpfull. My problem is that I want to use it in a customize way an I am not able.
Usual:
return this.customerRepository.findById(idCustomer, filter);
My Case:
I donĀ“t want to attack the "id" of the model, I want to attack another field. I have tried serveral things, but as a resume an example:
return this.customerRepository.findOne({where: { idUser: currentUserProfile.id }}, filter));
If I do that, the filter stop working. Any idea of how to mix a field in the model different than the id and the filter of loopback 4?
Thanks in advance
Best regards

#Jota what do you mean the filter stopped working? You have the correct idea about the approach. to search by a specific field just put it in the where clause as such:
this.customerRepository.findOne({ where: { <field_name>: <value_to_search> } })
e.g.
const filter = {
where: {
email: 'hello#world.com'
}
};
const result = await this.customerRepository.findOne(filter);

Related

Search string value inside an array of objects inside an object of the jsonb column- TypeORM and Nest.js

the problem I am facing is as follows:
Search value: 'cooking'
JSON object::
data: {
skills: {
items: [ { name: 'cooking' }, ... ]
}
}
Expected result: Should find all the "skill items" that contain 'cooking' inside their name, using TypeORM and Nest.js.
The current code does not support search on the backend, and I should implement this. I want to use TypeORM features, rather than handling it with JavaScript.
Current code: (returns data based on the userId)
const allItems = this.dataRepository.find({ where: [{ user: { id: userId } }] })
I investigated the PostgreSQL documentation regarding the PostgreSQL functions and even though I understand how to create a raw SQL query, I am struggling to convert this to the TypeORM equivalent.
Note: I researched many StackOverflow issues before creating this question, but do inform me If I missed the right one. I will be glad to investigate.
Can you help me figure out the way to query this with TypeORM?
UPDATE
Let's consider the simple raw query:
SELECT *
FROM table1 t
WHERE t.data->'skills' #> '{"items":[{ "name": "cooking"}]}';
This query will provide the result for any item within the items array that will match exact name - in this case, "cooking".
That's totally fine, and it can be executed as a raw request but it is certainly not easy to maintain in the future, nor to use pattern matching and wildcards (I couldn't find a solution to do that, If you know how to do it please share!). But, this solution is good enough when you have to work on the exact matches. I'll keep this question updated with the new findings.
use Like in Where clause:
servicePoint = await this.servicePointAddressRepository.find({
where: [{ ...isActive, name: Like("%"+key+"%"), serviceExecutive:{id: userId} },
{ ...isActive, servicePointId: Like("%"+key+"%")},
{ ...isActive, branchCode: Like("%"+key+"%")},
],
skip: (page - 1) * limit,
take: limit,
order: { updatedAt: "DESC" },
relations:["serviceExecutive","address"]
});
This may help you! I'm matching with key here.

nestjsx/crud: How do define an alias for a filter field

I have a nested typeorm OneToOne field in my model, call it Entity.related_entity. It's exposed to the API through the use of Nest/Crud endpoint.
I want to use the CRUD filter to filter on the related_entity fields, but currently it's only possible via ?filter=related_entity.some_field||$eq||10. How to make it so that it's possible to filter like this ?filter=some_field||$eq||10?
I do not think there is a way to register an alias for a filter. Assuming you are using the #Crud decorator on your controller, I think your best option would be the filter attribute of the query option (documented here). It allows you to register a function to transform your query search condition. In your case, you could have something like the following. Note that I have not tested that code and it might not work "as is", it is simply meant to give an idea of what the solution could look like.
function findAndReplaceAliases(search: SCondition) {
search.$and.map((filter) =>
filter.keys().contains('some_field')
? { 'related_entity.some_field': filter['some_field'] }
: filter
);
}
#Crud({
query: {
filter: findAndReplaceAliases
}
})
#Controller()
SomeController {}

Sequelize WHERE force one condition or not depending on a programmatically condition

I have a bool field in my DB and an endpoint to query that model.
The user sends the bool field is_social_field, if the value is true, I need to force to query only true values, otherwise return it if is true or false.
I managed to do with an OR condition, but I would like to have another solution, this does not seem the best practise. What do you guys think?
const { is_social_field } = req.body;
...
where{
[Op.or]: [{is_social: true}, {is_social: is_social_field}]
}
You can create the query object using the ternary operator like this:
const whereClause = req.body.is_social_field ? {is_sovial:true}:{};
And then use it with spread operator like this in the where clause:
where :
{
...whereClause
}
const { is_social_field } = req.body;
Now you can use the is_social_field to construct the db query. We have 2 scenario's to take care of here.
1. When we need all results irrespective of is_social_field. An appropriate query for that would be without the is_social field.
Like where = {}
2. When we need to filter results based on is_social_field. That query would be where = {is_social: is_social_field}
These two can be achieved via a ternary operator as pointed out in #khopadi's answer
You can also extend object assignment to get rid of the ternary operator too like
const where = {...is_social_field && {is_social:true}}

Mongoose-How to specify more than one attribute value in querys?

I have this mongoose query and I want to add the condition estadoPedido:"Agendado" to it? How can I do it?
Request.countDocuments(
{ estadoPedido: "Pendente", paciente: req.body.paciente }
If I understand you question right, you need to search for documents which have
- estadoPedido = 'Pendente' or 'Agendado'
- and paciente = req.body.paciente
you can use $in operator, something like this
Request.countDocuments({
estadoPedido: { $in: ['Pendente', 'Agendado'] },
paciente: req.body.paciente
})
hope it helps
you can also add multiple where clauses
Request.countDocuments()
.where("estadoPedido")
.in(['Pendente', 'Agendado'])
.where("prop2")
.in(["val1","val2"])

Query by Date Range for a column field in Sequelize

I'm trying to query a database with Sequelize to get items that were created between a certain date range. I used the $between operator but I don't seem to be getting anything.
{ where: {"createdAt":{"$between":["2018-03-31T21:00:00.000Z","2018-05-30T05:23:59.007Z"]}} }
Can anyone help with how I can achieve this?
I also had the same problem, I was getting empty array in response. The problem got fixed using :
const Op = Sequelize.Op;
and then using [Op.between] as shown below:
where: {
createdAt: {
[Op.between]: ["2018-07-08T14:06:48.000Z", "2019-10-08T22:33:54.000Z"]
}
}
Hope it helps :)
$between syntax seems to be right. There are no issues with the way you used. I tried to replicate with the following query
model.findAll({
where: {
created_at: {
"$between": ["2018-03-31T21:00:00.000Z","2018-05-30T05:23:59.007Z"]
}
}
})
The only change is, I use created_at instead of createdAt. Make sure that your column name is right. If it is not, it should have thrown SequelizeDatabaseError. Look for it.
If everything else is right, then you might not be having data in that date range :)

Resources