NestJS getting param from array matching - nestjs

I don't know how to get matched param from this definition:
#Get(['FAVORITE', 'RATING', 'FAVORITE_AND_RATING'])
find(...): Promise<Array<any>> {
/// how to get param what was matched
}

It is maybe just a workaround but it should work
#Get(['FAVORITE', 'RATING', 'FAVORITE_AND_RATING'])
find(#Param('FAVORITE') favorite: string, #Param('RATING') rating: string,
#Param('FAVORITE_AND_RATING') favorite_and_rating: string): Promise<Array<any>> {
if(favorite) {
//stuff to do
} else if(rating) {
//stuff to do
} else if(favorite_and_rating) {
//stuff to do
}
}

Related

Specify response type for inline fragment graphql in js file

Here, inline fragment graphql is used. I'm not able to write the return type in the js file.
Graphql:
query MyQuery {
samples(dataset: "", view: "") {
edges {
node {
... on ImageSample {
id
}
... on PointCloudSample {
id
}
}
}
}
}
JS file: this raises a syntax error:
const SAMPLE_DATA = {
edges: {
node: {
... on ImageSample {
id
sample
}
... on PointCloudSample {
id
}
}
}
};
I've also tried with node: {id} but didn't help
Cannot query field 'id' on type 'SampleItem'. Did you mean to use an inline fragment on 'Sample', 'ImageSample', 'PointCloudSample', or 'VideoSample'?
Calling the GraphQL query like this:
const gqlQuery = jsonToGraphQLQuery({
query: {
samples: {
__args: {
...data,
},
...SAMPLE_DATA
}
}
}, { pretty: true });
Can anyone help me how we need to write the SAMPLE_DATA response type?
I authored the GraphQL API. The below is a perfectly valid query as of v0.18.0.
query {
samples(dataset: "datasetName", view: []) {
edges {
node {
... on ImageSample {
id
}
... on PointCloudSample {
id
}
}
}
}
}
I believe you just need to follow the json-to-graphql-query instructions for querying with multiple inline fragments.
const SAMPLE_DATA = {
edges: {
node: {
__on: [
{ __typeName: "ImageSample", id: true },
{ __typeName: "PointCloudSample", id: true }
]
}
}
};

How can a nested field in graphQL query get its own arguments

I'm working on a cursor based pagination that requires the a nested field to access the args. So far, i've been unable to get the args to its desired field.
type Game {
players(first: Int, after: String, last: Int, before: String): GameToPlayerConnection
}
game(id: GameID!): Game
I am able to only access the args passed to the game and not the args passed to the players.
game: async (parent: any, args: { id: string; first: number; last: number; after:
string; before: string; }, _ctx: any, info: any) =>
{
const { id, first, last, after, before } = args;
console.log("args", args);
}
game(id: 'fortnite', first: 3){
players(first: 2){
....
}
}
I am trying to access the args passed to the players
That's correct. Every resolver can only access the arguments for its own property. Each object also has its own set of resolvers, so you need one object for Query, and another for Game:
const resolvers = {
Query: {
game: async (parent, { id }, context, info) {
return games.load(id);
},
},
Game: {
players: async ({ id }, { first, last, before, after }, context, info) {
return playersByGame({
gameId: id,
first,
last,
before,
after,
});
},
},
};

"Abstract type X must resolve to an Object type at runtime for field Query.user with value

this my code
schema
gql`
type Query {
user: X!
}
type User {
name: String!
}
type Time {
age: Int!
}
union X = User | Time
`;
resolvers
{
X: {
__resolveType: obj => {
if (obj.name) return { name: "Amasia" };
if (obj.age) return { age: 70 };
return null;
}
},
Query: {
user: () => {
return {
name: "Amasia"
};
}
}
}
request
query {
user{
... on User {
name
}
... on Time {
age
}
}
}
When I make a request do I get Error
"Abstract type X must resolve to an Object type at runtime for field Query.user with value { name: \"Amasia\" }, received \"{ name: \"Amasia\" }\". Either the X type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."
What is the reason.?
The resolveType function should return a string with the name of the concrete type the abstract type should resolve to. You are returning an object, not string. In this case, you should return "User" or "Time".
Simply add the __typename to the object to resolve it:
{
Query: {
user: () => {
return {
__typename: 'User',
name: "Amasia"
};
}
}
}

Mongoose - find matching array values

I'm creating a REST API with Node.js using Mongoose to access my backend MongoDB database. I have an array (variations) inside of one of my collections (also variations) and need to retrieve the object in the array that matches a provided value.
So far I've got this which returns an empty value...
//Get variation by ID
app.get('/v1/:id', async (request, response) => {
try {
var result = await variationsModel.find({ 'variationID': request.params.id }).exec();
response.send(result);
} catch (error) {
response.status(500).send(error);
}
})
And here's the model I've defined in the API...
const variationsModel = mongoose.model("variations", {
"variations": [
{
"variationID": String,
"custID": String,
"projID": String,
"variationTitle": String,
"variationDesc": String,
"variationStatus": String,
"variationChargeable": String,
"variationCost": String,
"requireMaterial": String,
"variationRequestor": String,
"variationCreationDate": String,
"variationImages": [
{
"imageId": String
}
],
"variationCategory": String
}
]
});
Anyone point me in the right direction?
Thanks!
The query should be
variationsModel.find({ 'variations.variationID': request.params.id }).exec();

Dynamic default scopes in sequelize.js

I am building kind of multitenancy using sequelize.js. Technically I need to filter all queries by predefined column and dynamic value of the current context. General idea was to use defaultScope to filter out other contexts, something like:
var context = () => { return "some current context id"; }
connection.define('kid', {
firstName: Sequelize.STRING,
photoUrl: Sequelize.STRING,
context: {
type: Sequelize.STRING,
defaultValue: context // this part works, it accepts function
}
}, {
defaultScope: {
where: {
context: context // this does not work, it does not accept function and values is defined only once
}
}
});
However this does not work because defaultScope is defined on the application start.
What is the right way to do this?
The problem is that Sequelize scopes are defined on the model but you need to apply the scope just before the query because that's when you have context such as the user and role.
Here's a slightly modified copy of the scope merge function from Sequelize which you can use in your hooks such as beforeFind()
// Feel free to write a more fp version; mutations stink.
const {assign, assignWith} = require('lodash')
const applyScope = ({scope, options}) => {
if (!scope) {
throw new Error('Invalid scope.')
}
if (!options) {
throw new Error('Invalid options.')
}
assignWith(options, scope, (objectValue, sourceValue, key) => {
if (key === 'where') {
if (Array.isArray(sourceValue)) {
return sourceValue
}
return assign(objectValue || {}, sourceValue)
}
else if (['attributes', 'include'].indexOf(key) >= 0
&& Array.isArray(objectValue)
&& Array.isArray(sourceValue)
) {
return objectValue.concat(sourceValue)
}
return objectValue ? objectValue : sourceValue
})
}
In your model:
{
hooks: {
beforeFind(options) {
// Mutates options...
applyScope({
scope: this.options.scopes.user(options.user)
, options
})
return options
}
}
, scopes: {
user(user) {
// Set the scope based on user/role.
return {
where: {
id: user.id
}
}
}
}
}
Finally in your query, set an option with the context that you need.
const user = {id: 12, role: 'admin'}
YourModel.findOne({
attributes: [
'id'
]
, where: {
status: 'enabled'
}
, user
})
I'm not sure it will help, but you can override a model default scope anytime.
let defaultScope = {
where: {
context: ""
}
};
defaultScope.where.context = context();
model.addScope('defaultScope',defaultScope,{override: true});
Maybe too late here but scopes can take arguments if defined as functions. From documentation Sequelize scope docs if the scope is defined as
scopes: {
accessLevel (value) {
return {
where: {
accessLevel: {
[Op.gte]: value
}
}
}
}
sequelize,
modelName: 'project'
}
you can use it like: Project.scope({ method: ['accessLevel', 19]}).findAll(); where 19 is the dynamic value the scope will use.
As per defaultScope I'm not sure it can be defined as a function

Resources