How can i remove element in postgresql json[] - node.js

in picture the column node_info was the type of json[], and now i want to
remove one element of the array by Nodejs ORM sequelize
function demo(){
const removeQuery = {
where: {
name: _name
},
raw: true
}
const updateNode = {
node_info: db.sequelize.fn('array_remove', db.sequelize.col('node_info'), JSON.stringify({uuid: uuid}))
}
db.Config.update(updateNode, removeQuery);
}
but i got this error:
ERROR: could not identify an equality operator for type json
Query failed
PostgreSQL said: could not identify an equality operator for type json
I'd appreciate any help you could give me!
Thanks :)

Related

Optional parameters on sequelize query

Good morning.
I'm quite new to NodeJS / sequelize world and I'm currently facing a problem while trying to display a dashboard on screen.
This dashboard has three filters: two dates (period), client name, and employee name. The user can select none, one, two, or all the filters and my database needs to work accordingly.
That being said, my problem is with Sequelize because I don't know how to treat this problem of parameters not being "always" there.
I've seen this question:
Sequelize optional where clause parameters?
but this answer doesn't work anymore. I also tried another way of building the where clause, but I failed on it as well (mainly due to sequelize operators).
The last thing I tried was to make a single query with all parameters included but try to find some value (or flag) that would make sequelize ignore the parameter, for the case when the parameter was no there*, but it looks like Sequelize doesn't have anything like that.
* I've read a question here that has an answer saying that {} would do the trick but I tried that as well but didn't work.
In summary: I need to make a query that can "change" over time, for example:
Foo.findAll({
where: {
id : 1,
}
});
Foo.findAll({
where: {
id {
[Op.in] : [1,2,3,4,5]
},
name: "palmeiira",
}
});
Do you know a way of doing it without the need of using a lot if / switch statements?
I'm currently using Sequelize v. 5.5.1.
Update
I tried doing as suggested by #Anatoly and created a function to build the parameters. It was something like that. (I tried a "smaller" version just to test)
async function test() {
const where = {};
where[Op.and] = [];
where[Op.eq].push({
id: {
[Op.in]: [1,2,3]
}
});
return where;
}
I setted the return value to a const:
const query = await test()
And tried console.log(query)
The result was: { [Symbol(and)]: [ { id: [Object] } ] }, which made me believe that the problem was parsing the Op part so i tried using 'Op.and' and 'Op.in' to avoid that and it solved this problem, but led to another on sequelize that said Invalid value
Do you have any idea where is my error ?
P.S.: #Anatoly very nice idea you gave me on original answer. Thank you very much.
If these three conditions should work together then you can use Op.and with an array of conditions:
const where = {}
if (datesFilter || clientNameFilter || employeenameFilter) {
where[Op.and] = []
if (datesFilter) {
where[Op.and].push({
dateField: {
[Op.between]: [datesFilter.start, datesFilter.finish]
}
})
}
if (clientNameFilter) {
where[Op.and].push({
name: {
[Op.iLike]: `%${clientNameFilter.value}%`
}
})
}
if (employeenameFilter) {
where[Op.and].push({
employeeName: {
[Op.iLike]: `%${employeenameFilter.value}%`
}
})
}
}
const dashboardItems = await DashboardItem.findAll({ where }, {
// some options here
})
If the conditions should work as alternatives then just replace Op.and with Op.or

`parseValue` are not called for input parameter of a customised scalar type

I define a schema like this:
const query = new GraphQLObjectType({
name: 'Query',
fields: {
quote: {
type: queryType,
args: {
id: { type: QueryID }
},
},
},
});
const schema = new GraphQLSchema({
query,
});
The QueryID is a customised scalar type.
const QueryID = new GraphQLScalarType({
name: 'QueryID',
description: 'query id field',
serialize(dt) {
// value sent to the client
return dt;
},
parseLiteral(ast) {
if (ast.kind === 'IntValue') {
return Number(ast.value);
}
return null;
},
parseValue(v) {
// value from the client
return v;
},
});
client query
query {
quote(queryType: 1)
}
I found that the parseValue method is not called when clients send query to my server. I can see parseLiteral is called correctly.
In most of the document I can find, they use gql to define schema and they need to put scalar QueryID in their schema definition. But in my case, I am using GraphQLSchema object for schema. Is this the root cause of that? If yes, what is the best way to make it works? I don't want to switch to gql format because I need to construct my schema at runtime.
serialize is only called when sending the scalar back to the client in the response. The value it receives as a parameter is the value returned in the resolver (or if the resolver returned a Promise, the value the Promise resolved to).
parseLiteral is only called when parsing a literal value in a query. Literal values include strings ("foo"), numbers (42), booleans (true) and null. The value the method receives as a parameter is the AST representation of this literal value.
parseValue is only called when parsing a variable value in a query. In this case, the method receives as a parameter the relevant JSON value from the variables object submitted along with the query.
So, assuming a schema like this:
type Query {
someField(someArg: CustomScalar): String
someOtherField: CustomScalar
}
serialize:
query {
someOtherField: CustomScalar
}
parseLiteral:
query {
someField(someArg: "something")
}
parseValue:
query ($myVariable: CustomScalar) {
someField(someArg: $myVariable)
}

Why is my Mongoose find query not returning the expected data?

The following function is to return all menu items of a specific type. The types exist in the database but the query is returning no data. Without the query criterion: {type:menuItem}, it returns the data with the the type.
exports.get = async (menuItem) => {
console.log(chalk.green('menuItem', menuItem));
try {
const menu = await Menu.find({type:menuItem});
console.log('menu', menu);
return menu;
} catch(error) {
console.log(error)
}
}
MenuItem logged to the console as shown in the function above produces the following. The problem seem to be with the variable, menuItem, because when I hard-code, {type:'pizza'}, it works.
console.log(chalk.green('menuItem', menuItem));
menuItem 'pizza'
The anuglar query string looks like the following, is there a problem with this:
private menuUrl = '/api/menu?menuItem="pizza"';
Sample data from the database:
{ quantity: 1,
toppings: [ 'chipotle-steak', 'red-onions' ],
_id: 5d163a7ae7179a4e432b501a,
type: 'pizza',
name: 'CHIPOTLE STEAK',
price: 15,
img: 'Chipotle-Steak.png',
}
The key type is used to tell mongoose about the type of that particular field. thats why using type as a field in mongoose schema can sometimes behave ambiguously.
Kindly change type to kind and search with {kind : menuItem} and it should work for you.
Dont forget to update all the docs from type to kind.
To update :
Menu.update({},{$rename : {'type' : 'kind'}},{multi:true})
Then find using kind
const menu = await Menu.find({kind:menuItem});
Silly mistake. The Angular query string had single quotes around pizza:
private menuUrl = "/api/menu?menuItem='pizza'";
It should have been without quotes instead:
private menuUrl = "/api/menu?menuItem=pizza";

Getting error while inserting bulk data using bulkCreate in Sequelize

I am trying to insert a lot of data i database using Sequelize library
but it is showing some strange as I am passing an array of objects into the bulkCreate query .
I have function something like this
db.organizations
.findAll({
attributes: ['name'],
where: {
id: req.ORG_ID
}
})
.then(org => {
let i; let smsData = [];
for (i = 0; i < user.length; i++) {
let DefaultText = Utils.defaultMessage(
user[i].name,
user[i].dataValues.amount,
org[0].name
);
smsData.push({
organizationId:
user[i].dataValues.organizationEntries[0].organizationId,
mobile: user[i].mobile,
message: DefaultText,
status: 0
});
}
console.log(JSON.stringify(smsData));
db.logSms.bulkCreate([{
smsData
}]).then(() => { // Notice: There are no arguments here, as of right now you'll have to...
return db.logSms.findAll({ where: { status: 0 } });
}).then(sms => {
console.log(sms)
})
and I have also done console.log(smsData) which is showing array of objects but I am not able to understand why I am facing this error.
INSERT INTO log_sms (id,created_at,updated_at) VALUES (NULL,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);
Unhandled rejection SequelizeDatabaseError: Field 'mobile' doesn't have a default value
This error is basically coming as while executing the query as u can see below the error as I have made mobile field compulsory and I am passing the array of objects which is having mobile number but still this error is coming. Please give some hint
I have got my mistake as I should remove the braces from this statement:
db.logSms.bulkCreate([{ smsData }])
it should be like this:
db.logSms.bulkCreate(smsData)

How to use graphql-type-json package with GraphQl

I can't get GraphQL to recognize the JSON scalar type.
I followed the [apollo docs] (http://dev.apollodata.com/tools/graphql-tools/scalars.html#Using-a-package) to define a JSON GraphQL scalar type for my schema:
Schema:
const SchemaDefinition = `
scalar JSON
schema {
query: Query
mutation: Mutation
}
`
export default [
SchemaDefinition,
Query,
Mutation,
...
]
Test type:
const Test = `
type Test {
bodyJson: JSON
}`
Resolver:
import GraphQLJSON from 'graphql-type-json'
const QueryResolver = {
Query: {
viewer(root, args, ctx) {
return User.query()
.where('id', ctx.state.user)
.first()
}
}
}
const scalarJSON = {
JSON: GraphQLJSON
}
export default {
...QueryResolver,
...ViewerResolver,
...scalarJSON
...
}
I'm using PostgreSQL and the column I'm querying (body_json) is of data type jsonb.
If I test my schema through GraphiQL, when I return the value straight from the db (I use Knex to query) I get this error message from GraphQL:
Expected a value of type \"JSON\" but received: [object Object]
If I use JSON.stringify first on the returned value, I get this error:
"Expected a value of type \"JSON\" but received: {\"key\":\"test\"}"
Any suggestion as to what I might be doing wrong?
I resolved custom scalar JSON like this in resolvers
JSON: {
__serialize(value) {
return GraphQLJSON.parseValue(value);
} }
And It worked fine for me. I think it will help you
I couldn't get a custom scalar working with a text-based schema (using buildSchema('...') from the core "graphql" library), but it worked when I built the schema programmatically from scratch (using new GraphQLSchema(...)).

Resources