sequelize group by result undefined - group-by

i'm trying to get the result from sequelize query group by
but when i want to get the value of count , it shows undefined
var models = require('../../config/sequelize');
models.device.findAll({
attributes: [
'type',
[models.sequelize.fn('count', models.sequelize.col('deviceId')),'count']
],
group: ["device.type"]
}).then(function (result) {
result.forEach( function(e){
console.log( e.count ) ;
})
}).catch(function(err) {
console.log( "test group :"+JSON.stringify(err.message)) ;
}); ;

Assuming type and deviceId are the actual column name and not the aliases, try using raw: true and set columns using sequelize:
device.findAll({
raw: true,
attributes:[
Sequelize.col('type'),
[Sequelize.fn('count', Sequelize.col('deviceId')), 'count']
],
group: [
'device.type'
]
})
.then( devices => {
console.log(devices.count); // or
console.log(devices['count'])
})
.catch(/* */);

Related

Sequelize (Postgres) always 'returning' null for second index (whether creating or updating)

Trying to correctly troubleshoot HTTP status codes and responses on upsert. I've scoured SO and google to find examples of this behavior, but the answers are always really old (pre Sequelize 6 era).
From what I gather over at Sequelize docs, UPSERT returns Promise<Model,boolean | null> and additionally For SQLite/Postgres, created value will always be 'null'. But apparently for me, whether it created/didn't update/updated, it always returns null
Am I correctly understanding that boolean return will return for update(T)/no update(F) and null for creation? Or will it only return null whether create|update|no update for postgres users?
This is MY expected return behavior:
data: [
{
id: 64920,
...etc...
},
null // null = created
],
data: [
{
id: 64921,
...etc...
},
false // false = no update (data is the same)
],
data: [
{
id: 64922,
...etc...
},
true // true = update complete (some data was new)
]
Sample controller upsert command:
exports.createOne = async (req, res, next) => {
Trip.upsert({
id: req.body.id,
...etc...
},{returning: true } // not needed, default in Sequelize =< 6.0
)
.then(function (test) {
if (test) {
res.status(200);
res.send("Successfully stored");
} else {
res.status(200);
res.send("Successfully inserted");
}
})
.catch((err) => {
res.status(500).json({ error: err.message });
});
};
Anyone have examples or suggestions to properly implement this?
Thank you!

Redux Toolkit Query: Reduce state from "mutation" response

Let's say I have an RESTish API to manage "posts".
GET /posts returns all posts
PATCH /posts:id updates a post and responds with new record data
I can implement this using RTK query via something like this:
const TAG_TYPE = 'POST';
// Define a service using a base URL and expected endpoints
export const postsApi = createApi({
reducerPath: 'postsApi',
tagTypes: [TAG_TYPE],
baseQuery,
endpoints: (builder) => ({
getPosts: builder.query<Form[], string>({
query: () => `/posts`,
providesTags: (result) =>
[
{ type: TAG_TYPE, id: 'LIST' },
],
}),
updatePost: builder.mutation<any, { formId: string; formData: any }>({
// note: an optional `queryFn` may be used in place of `query`
query: (data) => ({
url: `/post/${data.formId}`,
method: 'PATCH',
body: data.formData,
}),
// this causes a full re-query.
// Would be more efficient to update state based on resp.body
invalidatesTags: [{ type: TAG_TYPE, id: 'LIST' }],
}),
}),
});
When updatePost runs, it invalidates the LIST tag which causes getPosts to run again.
However, since the PATCH operation responds with the new data itself, I would like to avoid making an additional server request and instead just update my reducer state for that specific record with the content of response.body.
Seems like a common use case, but I'm struggling to find any documentation on doing something like this.
You can apply the mechanism described in optimistic updates, just a little bit later:
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query'
import { Post } from './types'
const api = createApi({
// ...
endpoints: (build) => ({
// ...
updatePost: build.mutation<void, Pick<Post, 'id'> & Partial<Post>>({
query: ({ id, ...patch }) => ({
// ...
}),
async onQueryStarted({ id, ...patch }, { dispatch, queryFulfilled }) {
const { data } = await queryFulfilled
dispatch(
api.util.updateQueryData('getPost', id, (draft) => {
Object.assign(draft, data)
})
)
},
}),
}),
})

Variables exporting error in MongoDB error

Question
I have provided my code below for reference. I'm using MongoDB and discord.js v12. So basically, I have made a !info command which shows some general info of the user.
What this code does is, it checks through the member's roles, and regarding which role they have, it calculates their total claim time (for giveaways etc.). The problem here, is with the donator role. I can't figure out why I can't use the donates variable outside the db.findOne block. Here, data.content.length shows the total donates of the users, which means donates * 5 is +5 claim time for each donate.
My Code
const moment = require('moment');
module.exports = {
name: 'info',
async execute(client, message, args, Discord){
const member = message.mentions.members.first() || message.guild.members.cache.get(args[0]) || message.member;
const db = require('../models/d-schema');
db.findOne({ guildid: message.guild.id, user: member.user.id }, async(err, data)=>{
if(err) throw err;
if(data){
const donates = parseInt(data.content.length);
}
})
var DefaultTime = 10;
var support = 0;
var donate = 0;
var boost = 0;
const userRoles = member.roles.cache.map((r) => r.name);
if (userRoles.includes("୨・supporter")) {
support = 3;
}
if (userRoles.includes("୨・donator")) {
donate = donates * 5;
}
if (userRoles.includes("୨・booster")) {
boost = 10;
}
const TotalTime = DefaultTime + support + donate + boost;
const embed = new Discord.MessageEmbed()
.setThumbnail(member.user.displayAvatarURL( {dynamic: true} ))
.addFields(
{name: member.user.tag, value: member.user, inline: true},
{name: 'Nickname', value: `${member.nickname !== null ? member.nickname : 'None'}`, inline: true},
{name: 'Is Bot', value: member.user.bot, inline: true},
{name: 'Joined', value: `${moment.utc(member.joinedAt).format("MMMM Do YYYY")}`, inline: true},
{name: 'Created', value: `${moment.utc(member.user.createdAt).format("MMMM Do YYYY")}`, inline: true},
{name: 'Claim Time', value: `${TotalTime} seconds`, inline: true},
)
.setFooter(`ID : ${member.user.id}`)
.setTimestamp()
.setColor('00ffcc')
message.channel.send(embed)
}
}
You cannot use the donates variable because you are declaring it inside the db.findOne() block. This is called variables scope. For better understanding you can read this answer.
If you want to use it outside of that block, you have to declare it beforehand, like this:
let donates;
db.findOne({ guildid: message.guild.id, user: member.user.id }, async(err, data)=>{
if(err) throw err;
if(data){
donates = parseInt(data.content.length);
}
})
Now you're able to use that variable outside of the db.findOne() block :)
Edit:
Alternative way:
It would be easier to use the function asynchronously. That way, everything can be scoped in the same block!
Example:
These two methods will give the same results:
const data = await Model.findOne({ ... });
console.log(data);
Model.findOne({ ... }, (err, data) => {
console.log(data);
});
Suggestion from Lioness100

Issue Populating Filter Value for AG Grid agSetColumnFilter

I'm trying to populate the value for the agSetColumnFilter, but I'm getting an error that I cannot find anything where in documentation (or anywhere online). Has anyone ever run into this issue?
This is what the column definition looks like:
columnDefs.push({
headerName: col.name,
field: col.name,
def: col,
rowGroup: k < groupedColumnCount ? true : false,
pinned: k < _this.groupBy.length ? 'left' : null,
lockPinned: k < _this.groupBy.length ? true : false,
hide: k < groupedColumnCount ? true : false,
suppressToolPanel: _this.groupBy.length ? true : false,
valueGetter: function(data){
if(data.data){
var def = data.colDef.def;
var value = data.data[data.colDef.field];
if(value){
return value.value;
}else{
return null;
}
}else{
return data.value;
}
},
valueFormatter: function(data){
if(data.data){
var def = data.colDef.def;
var value = data.data[data.colDef.field];
if(!value) return null;
if(value.formatted){
_this.cache[data.colDef.field + value.value] = value.formatted;
}
return value.formatted ? value.formatted : value.value;
}else{
if(_this.cache[data.colDef.field + data.value]){
return _this.cache[data.colDef.field + data.value];
}else{
return data.value;
}
}
},
keyCreator: function(params){
console.log(params);
},
filter: 'agSetColumnFilter',
filterParams: {
values: function (params) {
params.success([{
$uri: 'nhuihi',
value: {
$value: 'some text'
}
}]);
}
}
});
I'm only printing out keyCreator params for now since I don't know what will actually be available in the data. The idea is that I can set values using complex objects returned from the server and display a formatted value instead of a key. This is the error I'm getting.
ag-grid-enterprise.min.noStyle.js:formatted:27684 Uncaught TypeError: Cannot read property 'onFilterValuesReady' of undefined
at t.setFilterValues (ag-grid-enterprise.min.noStyle.js:formatted:27684)
at e.modelUpdatedFunc (ag-grid-enterprise.min.noStyle.js:formatted:27609)
at e.onAsyncValuesLoaded (ag-grid-enterprise.min.noStyle.js:formatted:27917)
at values (comparison-table-v7.js:1253)
at e.createAllUniqueValues (ag-grid-enterprise.min.noStyle.js:formatted:27909)
at new e (ag-grid-enterprise.min.noStyle.js:formatted:27867)
at t.initialiseFilterBodyUi (ag-grid-enterprise.min.noStyle.js:formatted:27608)
at t.init (ag-grid-enterprise.min.noStyle.js:formatted:18945)
at e.initialiseComponent (ag-grid-enterprise.min.noStyle.js:formatted:10602)
at e.createAgGridComponent (ag-grid-enterprise.min.noStyle.js:formatted:10574)
Here's a test case for it as well. I simply modified the example by AG Grid. https://plnkr.co/edit/GURQHP0KKFpJ9kwaU83M?p=preview
If you open up console, you will see an error when you click on Athletes filter.
Also reported on GitHub: https://github.com/ag-grid/ag-grid/issues/2829
If you need to configure filter values without async requests
filterParams: {
values: getFilterValuesData()
}
getFilterValuesData(){
//data preparation
//little bit modified sample to present that you can handle your logic here
let data = [];
[
'John Joe Nevin',
'Katie Taylor',
'Paddy Barnes',
'Kenny Egan',
'Darren Sutherland',
'Margaret Thatcher',
'Tony Blair',
'Ronald Regan',
'Barack Obama'
].forEach(i=>{
data.push(i);
});
return data;
}
If it requires to make an async request for data preparation you can use callback function:
filterParams: {
values: (params)=>{
setTimeout(()=>{ -- setTimeout on this case only for async request imitation
params.success(['value 1', 'value 2'])
}, 5000)
}
}
Notice: params.success(...) should be used only with an async request
Doc: ag-grid Asynchronous Values

OrientJS: How to get standard JSON (serialized) from query

I don't understand how to get standard JSON back from an orientjs query. I see people talking about "serializing" the result, but I don't understand why or how to do that. There is a toJSON() method, but i only see it being used with fetchplans etc...
I am trying to pipe a stream to a csv file and it isn't working properly because of the incorrect JSON format.
I would love an explanation of how and when to serialize. :-)
My Query:
return db.query(
`SELECT
id,
name,
out('posted_to').name as page,
out('posted_to').id as page_id,
out('posted_to').out('is_language').name as language,
out('posted_to').out('is_network').name as network
FROM post
WHERE posted_at
BETWEEN
'${since}'
AND
'${until}'
UNWIND
page,
page_id,
language,
network
`
My Result:
[ { '#type': 'd',
id: '207109605968597_1053732754639607',
name: '10 maneiras pelas quais você está ferindo seus relacionamentos',
page: 'Eu Amo o Meu Irmão',
page_id: '207109605968597',
language: 'portuguese',
network: 'facebook',
'#rid': { [String: '#-2:1'] cluster: -2, position: 1 },
'#version': 0 },
{ '#type': 'd',
id: '268487636604575_822548567865143',
name: '10 maneiras pelas quais você está ferindo seus relacionamentos',
page: 'Amo meus Filhos',
page_id: '268487636604575',
language: 'portuguese',
network: 'facebook',
'#rid': { [String: '#-2:3'] cluster: -2, position: 3 },
'#version': 0 }]
This is my dataset:
Query:
db.select('id','code').from('tablename').where({deleted:true}).all()
.then(function (vertex) {
console.log('Vertexes found: ');
console.log(vertex);
});
Output:
Vertexes found:
[ { '#type': 'd',
id: '6256650b-f5f2-4b55-ab79-489e8069b474',
code: '4b7d99fa-16ed-4fdb-9baf-b33771c37cf4',
'#rid': { [String: '#-2:0'] cluster: -2, position: 0 },
'#version': 0 },
{ '#type': 'd',
id: '2751c2a0-6b95-44c8-966a-4af7e240752b',
code: '50356d95-7fe7-41b6-b7d9-53abb8ad3e6d',
'#rid': { [String: '#-2:1'] cluster: -2, position: 1 },
'#version': 0 } ]
If I add the instruction JSON.stringify():
Query:
db.select('id','code').from('tablename').where({deleted:true}).all()
.then(function (vertex) {
console.log('Vertexes found: ');
console.log(JSON.stringify(vertex));
});
Output:
Vertexes found:
[{"#type":"d","id":"6256650b-f5f2-4b55-ab79-489e8069b474","code":"4b7d99fa-16ed-
4fdb-9baf-b33771c37cf4","#rid":"#-2:0","#version":0},{"#type":"d","id":"2751c2a0
-6b95-44c8-966a-4af7e240752b","code":"50356d95-7fe7-41b6-b7d9-53abb8ad3e6d","#ri
d":"#-2:1","#version":0}]
Hope it helps
I found a way that worked for me. instead of using :
db.query()
i used http request in node to query on database. on OrientDB Document also said you get only JSON format in result. this way if you query in database you will always get a valid JSON.
for making a http request i used request module.
this is a sample that worked for me :
var request = require("request");
var auth = "Basic " + new Buffer("root" + ":" + "root").toString("base64")
request(
{
url : encodeURI('http://localhost:2480/query/tech_graph/sql/'+queryInput+'/20'),
headers : {
"Authorization" : auth
}
},
function (error, response, body) {
console.log(body);
return body;
}
);