Object.values map data node js - node.js

I have to use the data I receive, in particular I have to be able to use the data in 'properties':
I don't understand how to call them, instead of console.log
I tried to use an Object.values(), but so I can't access the 'properties' data that I have to reuse later.
const response = await notion.databases.query({
database_id: databaseId,
page_size: 2
});
var effort_data = []
effort_data.push({
response
})
effort_data.map(data => {
Object.values(data.response.results).map((data) => {
console.log('data', data)
})
})
this is my response :
data {
object: 'page',
id: '3b8e203e-79ae-4ddc-ba3a-e0f5b30f4d4e',
created_time: '2023-01-25T13:51:00.000Z',
last_edited_time: '2023-01-25T13:59:00.000Z',
created_by: { object: 'user', id: '204c1b2e-0c59-4605-be45-de1fc9916416' },
last_edited_by: { object: 'user', id: '204c1b2e-0c59-4605-be45-de1fc9916416' },
cover: null,
icon: { type: 'emoji', emoji: '👽' },
parent: {
type: 'database_id',
database_id: '1b02ff59-8cdb-47fb-a6f9-5904bcecbe72'
},
archived: false,
properties: {
Assignees: { id: '%24v1Q', type: 'people', people: [] },
Type: { id: '9dB%5E', type: 'select', select: [Object] },
Progetti: {
id: '%3AirU',
type: 'relation',
relation: [Array],
has_more: false
},
Epics: { id: 'B%7BSE', type: 'relation', relation: [], has_more: false },
'Creato da': { id: 'D%5Dzr', type: 'created_by', created_by: [Object] },
'Flussi coinvolti': { id: 'EFdR', type: 'relation', relation: [], has_more: false },
'Sprint corrente?': { id: 'G%5Cvg', type: 'formula', formula: [Object] },
Sprint: { id: 'Jz.%40', type: 'multi_select', multi_select: [] },
'🏃 Sprint': { id: 'O%3DHc', type: 'relation', relation: [], has_more: false },
Settore: { id: 'XYh%5D', type: 'select', select: null },
Timeline: { id: '_G%2Bl', type: 'date', date: [Object] },
Tasks: {
id: 'bXv%3F',
type: 'relation',
relation: [Array],
has_more: false
},
'Data creazione': {
id: 'e_r%7D',
type: 'created_time',
created_time: '2023-01-25T13:51:00.000Z'
},
'Epic status': { id: 'nRGT', type: 'rollup', rollup: [Object] },
'Ultimo aggiornamento da': { id: 'ogbh', type: 'last_edited_by', last_edited_by: [Object] },
'Data ultimo aggiornamento': {
id: 'p%5CYK',
type: 'last_edited_time',
last_edited_time: '2023-01-25T13:59:00.000Z'
},
Priority: { id: '%7BMEq', type: 'select', select: [Object] },
Status: { id: '%7CF4-', type: 'select', select: [Object] },
Name: { id: 'title', type: 'title', title: [Array] }
},
url: 'https://www.notion.so/Endpoint-per-ordini-card-da-esterni-3b8e203e79ae4ddcba3ae0f5b30f4d4e'
}

Related

Node.js - Swagger - Unable to render this definition

I am following this toutorial: https://github.com/codeBelt/open-api-documentation/blob/master/src/openApiDocumentation.js
Can I validate my openApiDocumentation.js file somewhow? I get:
Unable to render this definition
The provided definition does not specify a valid version field.
Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).
I am attaching mi .js file. Maybe you guys will see a typo here. Thanks in advance.
.js file:
const USER_TYPES = {
EXCHANGE: 'xxx',
GIVEAWAY: 'xxx'
}
const openApiDocumentation = {
openapi: '3.0.1',
info: {
version: '1.3.0',
title: 'xxx',
description: 'xxx',
contact: {
name: 'xxx',
email: 'xxx',
}
},
license: {
name: 'Apache 2.0',
url: 'https://www.apache.org/licenses/LICENSE-2.0.html',
},
servers: [
{
url: 'http://localhost:4000/',
description: 'Local server',
},
],
tags: [
{
name: 'Books CRUD operations',
},
],
paths: {
'/findAllBooks': {
get: {
tags: ['CRUD operations'],
description: 'Get all Book offers',
operationId: 'getUsers',
parameters: [
{
name: 'page',
in: 'query',
schema: {
type: 'integer',
default: 1,
},
required: true,
description: 'Page numer used pagination.',
},
],
responses: {
'200': {
description: 'Books were obtained',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Books',
},
},
},
},
'500': {
description: 'Missing parameters',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Error',
},
example: {
message: 'page qyery parameter is missing',
internal_code: 'missing_parameters',
},
},
},
},
},
},
},
},
components: {
schemas: {
coverImg: {
type: 'string',
example: 'http:',
},
image: {
type: 'string',
example: 'http',
},
category: {
type: 'string',
example: 'Crafts & Hobbies',
},
linkTypes: {
type: 'object',
properties: {
coverImg: {
$ref: '#/components/schemas/coverImg',
},
images: {
type: 'array',
items: {
$ref: '#/components/schemas/image',
},
}
}
},
offerID: {
type: 'string',
example: '27301927',
},
userID: {
type: 'string',
example: 'efdc5192',
},
title: {
type: 'string',
example: 'Quilting For Dummies',
},
description: {
type: 'string',
example: 'You ',
},
categories: {
type: 'array',
items: {
$ref: '#/components/schemas/category',
},
},
links: {
type: 'object',
items: {
$ref: '#/components/schemas/linkTypes',
},
},
offerType: {
type: 'string',
enum: USER_TYPES,
default: USER_TYPES.EXCHANGE,
},
Book: {
type: 'object',
properties: {
offerID: {
$ref: '#/components/schemas/offerID',
},
userID: {
$ref: '#/components/schemas/userID',
},
title: {
$ref: '#/components/schemas/title',
},
description: {
$ref: '#/components/schemas/description',
},
categories: {
$ref: '#/components/schemas/categories',
},
imageLinks: {
$ref: '#/components/schemas/links',
},
offerType: {
$ref: '#/components/schemas/offerType',
},
},
},
Books: {
type: 'object',
properties: {
users: {
type: 'array',
items: {
$ref: '#/components/schemas/Book',
},
},
},
},
Error: {
type: 'object',
properties: {
message: {
type: 'string',
},
internal_code: {
type: 'string',
},
},
},
},
},
};
There are few mistakes,
license must be inside the info object
info: {
version: '1.3.0',
title: 'xxx',
description: 'xxx',
contact: {
name: 'xxx',
email: 'xxx' // make sure you have used valid email address!
},
license: {
name: 'Apache 2.0',
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
}
}
enum will allow only array not an object and here you have passed object USER_TYPES, corrected below:
const USER_TYPES = {
EXCHANGE: 'xxx',
GIVEAWAY: 'xxx'
};
const USER_TYPES_ENUM = [
USER_TYPES.EXCHANGE,
USER_TYPES.GIVEAWAY
];
offerType: {
type: 'string',
enum: USER_TYPES_ENUM,
default: USER_TYPES.EXCHANGE,
},
For best practice use https://editor.swagger.io/ (also they have provided a option to convert json to yaml under Edit > Convert to YAML)!

Slack Dialog.open not Opening if Variable is in Title

Whenever I try to add a variable to my dialog title, dialog.open does not work and no errors are thrown.
If I remove the variable from the title everything works fine, it is only when I add the variable to the title
I execute this before I define dialog
app.post('/create', function(req, res) {
var users = []
var {
text, trigger_id
} = req.body;
text = text.toUpperCase()
var issuetypes = []
axios({
method: 'get',
url: baseURL + 'project/' + text
}).then(function(response) {
for (var i = 0; i < response.data.issueTypes.length; i++) {
issuetypes.push({
label: response.data.issueTypes[i].name,
value: response.data.issueTypes[i].name
});
}
Does not work:
const dialog = {
token: botToken,
trigger_id,
dialog: JSON.stringify({
title: 'Create a new ' + text + ' Ticket',
callback_id: 'submit-ticket',
submit_label: 'Submit',
elements: [{
label: 'Project',
type: 'text',
name: 'project'
}, {
label: 'Summary',
type: 'text',
name: 'summary',
}, {
label: 'Description',
type: 'textarea',
name: 'description',
optional: true,
}, {
label: 'Type',
type: 'select',
name: 'type',
options: issuetypes,
}, {
label: 'Reporter',
type: 'select',
name: 'reporter',
optional: true,
options: [{
label: 'Reporter',
value: 'reporter'
}, ],
}, {
label: 'Link',
type: 'select',
name: 'epic',
optional: true,
options: [{
label: 'Epic',
value: 'epic'
}, ],
}, ],
}),
};
Works:
const dialog = {
token: botToken,
trigger_id,
dialog: JSON.stringify({
title: 'Create a new Ticket',
callback_id: 'submit-ticket',
submit_label: 'Submit',
elements: [{
label: 'Project',
type: 'text',
name: 'project'
}, {
label: 'Summary',
type: 'text',
name: 'summary',
}, {
label: 'Description',
type: 'textarea',
name: 'description',
optional: true,
}, {
label: 'Type',
type: 'select',
name: 'type',
options: issuetypes,
}, {
label: 'Reporter',
type: 'select',
name: 'reporter',
optional: true,
options: [{
label: 'Reporter',
value: 'reporter'
}, ],
}, {
label: 'Link',
type: 'select',
name: 'epic',
optional: true,
options: [{
label: 'Epic',
value: 'epic'
}, ],
}, ],
}),
};
Then I call dialog.open
axios.post("https://slack.com/api/dialog.open", qs.stringify(dialog))
.then(
(result) => {
res.send('');
}).catch(function(err) {
console.error(err);
})
}).catch(function(err) {
console.error(err);
})
});
Any ideas as to why dialog.open does not work?
The reason the Dialog is not shown when you have the variable in the title is that you exceed the maximum length of 24 chars for a title. (see here for reference)
You should however received the validation error from the API though as documented for the dialog.open method:
"The field `title` cannot be longer than 24 characters"
There must be another reason why you are not receiving it.

MongoDB $lookup pipeline match by _id not working

i'm trying to do a $lookup in a collection and add some data to my documents. The problem is that when i try matching my $lookup pipeline by _id it returns an empty array. Here is my code:
Schedule.aggregate([{ // My Schedule schema
$match: {
store: req.query.store,
"customer.id": req.query.user
}
},
{
$skip: +req.query.skip
}, {
$limit: +req.query.limit
},
{
$lookup: {
from: Employee.collection.name, // "employee" schema,
let: {
id: "$employee.id" // employee _id from the "schedule" collection match above
},
pipeline: [{
$match: {
$expr: {
"_id": "$$id" // here i try to match by _id
}
}
},
{
$project: { // the only fields i need
"_id": 1,
"avatar": 1,
"name": 1
}
}
],
as: "employees" // employees is returned as []
}
}
]).exec((err, resolve) => {
if (err) console.log('error', err);
res.json(resolve);
});
If it helps here's both my collections used in this aggregation:
Schedule schema:
const ScheduleSchema = new Schema({
store: {
type: String,
required: true
},
customer: {
id: {
type: String
},
name: {
type: String
},
avatar: String,
phone: {
type: String
},
email: { type: String },
doc: {
type: String
},
},
employee: {
id: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
name: {
type: String,
required: true
},
avatar: String,
},
service: {
id: {
type: String
},
name: {
type: String,
required: true
},
filters: [String]
},
info: {
channel: {
type: String,
required: true,
default: 'app'
},
id: mongoose.Schema.Types.ObjectId,
name: String
},
scheduleDate: {
type: String,
required: true
},
scheduleStart: {
type: String,
required: true
},
scheduleEnd: {
type: String,
required: true
},
value: {
type: Number
},
comissionType: {
type: String,
default: '$'
},
comissionValue: {
type: Number,
default: 0
},
status: {
type: Number,
required: true
},
observation: String,
paymentMethod: {
type: Number,
default: 0
},
paymentValue: String,
paymentChange: String,
color: String
}, {
timestamps: {
createdAt: 'created',
updatedAt: 'updated'
}
});
Employee Schema:
const EmployeeSchema = new Schema({
name: {
type: String,
required: true
},
a_to_z: String, // nome normalizado, só minusculas e sem espaços
description: String,
email: {
type: String,
required: true
},
avatar: String,
phone: {
type: String
},
storeOwner: {
type: Boolean,
required: true
},
permissions: [
{
route: String,
hasPermission: Boolean
}
],
scheduleAutomatic: {
type: Boolean,
required: true,
default: false
},
password: {
passwordHash: String,
salt: String
},
active: {
type: Boolean,
default: true
},
storeKey: {
type: String,
required: true
},
notification_token: String,
notification_tokens: {
type: [String],
default: []
},
workingHours: [{
weekDay: {
type: Number,
},
doesWork: {
type: Boolean,
},
startHour: String,
endHour: String,
lunchStart: String,
lunchEnd: String
}],
config: {
available_days: {
type: Number,
default: 365
},
in_advance_schedule: {
type: Number,
default: 0
},
in_advance_interval: {
type: String,
default: 'minute'
}
}
}, {
timestamps: {
createdAt: 'created',
updatedAt: 'updated'
}
});
EDIT
The result i'm trying to achieve is this:
The employees property is the one i'm trying to use $lookup to get, it'll have the same data as the employee property, in the end it'll be and array of objects with just one object inside.
Some sample docs:
Schedule:
color: "lavander",
created: "2018-07-31T18:50:53.423Z",
customer: {id: "5b60a67206e8a65f48a15f13", name: "Gabriel Barreto", phone: "11995274098", cpf: "40735255814"},
employee: {id: "5b2952c68424872fccece7f5", name: "Gabriel Barreto", avatar: null},
observation: "teste",
scheduleDate: "2018-08-01",
scheduleEnd: "2018-08-01 08:30",
scheduleStart: "2018-08-01 08:00",
service: {filters: Array(3), id: "5b606e8cc59e82354cc931e2", name: "Corte Masc"},
status: 1,
store: "5b16cceb56a44e2f6cd0324b",
updated: "2018-11-27T13:27:40.310Z",
value: 25,
__v: 0,
_id: "5b60af8de558661acc5d70b9"
Employee:
a_to_z: "gabrielbarreto",
active: true,
avatar: "gabriel_barreto_h7qvcn.jpg",
config: {available_days: 180, in_advance_schedule: 10, in_advance_interval: "hour"},
created: "2018-06-19T19:00:22.315Z",
currency: "BRL",
description: "Novo perfil",
email: "gabriel.barreto#wabiz.com.br",
lang: "pt-BR",
name: "Gabriel Barreto",
notification_token: "2d768670-6011-4873-846d-39580b0d82d0",
notification_tokens: ["53049a82-53dc-4bc3-9646-7a4bee1f367b"],
password: null,
permissions: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
phone: "11995274098",
scheduleAutomatic: false,
storeKey: "5b16cceb56a44e2f6cd0324b",
storeOwner: true,
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImdhYnJpZWwuYmFycmV0b0B3YWJpei5jb20uYnIiLCJpYXQiOjE1NTA2NzEwNDQsImV4cCI6MTU1MzI2MzA0NH0.0Odizd8pS4WPGSqm_2_XrTw1YE8NMOOXnHIrG-WVxGo",
updated: "2019-02-20T13:34:20.619Z",
workingHours: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
__v: 0,
_id: "5b2952c68424872fccece7f5"
Thanks for your time
I was in trouble too while using $lookup with mongoose to trying to match _id as my collection store the reference as a String and not an ObjectId
Model A: {_id: ObjectId("xxx"), b_id: "eeeee"}
Model B: {_id: ObjectId("eeeee")}
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [{$match: {$expr: {$eq: ["$_id", "$$id"]}}}],
as: b
}
])
In this example b is never filled as $$id is not considered as an ObjectId
Just add a project to transform $$id in an objectId and its working
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [
{$project: {_id: 1, bid: {"$toObjectId": "$$id"}}},
{$match: {$expr: {$eq: ["$_id", "$bid"]}}}
],
as: b
}
])
Or with foreignField, localField:
MyCollectionA.aggregate([
{
$project:{
_id: 1,
b_id: {"$toObjectId": "$b_id"}
}
},
{
$lookup: {
from: "collectionb",
localField: "b_id",
foreignField: "_id",
as: b
}
])
This worked for me:
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [
{$match: {$expr: {$eq: ["$_id", {"$toObjectId": "$$id"}]}}}
],
as: b
}
])

Nested Objects in GraphQL Schema in NodeJS

I'm creating a GraphQL Server using Node JS.
I'm trying to replicate the mongo Schema which has a nested object purely for organisation. This is my mongo schema:
var plansSchema = new Schema({
planName: {
type: String,
required: [true, "Plan name is required"]
},
pricing: {
monthly: Number,
scanEnvelope: Number,
initalScan: Number,
perPage: Number,
forwardMail: Number,
forwardParcel: Number,
shred: Number,
perMonthPerGram: Number,
freeStorePerGram: Number,
setup: Number,
idFree: Number
},
expires: Number,
private: Boolean,
deleted: Boolean,
date: { type: Date, default: Date.now },
});
I'm trying to replicate this in a GraphQL schema, so far I have the following:
const PlanType = new GraphQLObjectType({
name: "Plan",
fields: () => ({
id: { type: GraphQLString },
planName: { type: GraphQLString },
pricing: new GraphQLObjectType({
name: "Pricing",
fields: () => ({
expires: { type: GraphQLInt },
private: { type: GraphQLBoolean },
monthly: { type: GraphQLInt },
scanEnvelope: { type: GraphQLInt },
initalScan: { type: GraphQLInt },
perPage: { type: GraphQLInt },
forwardMail: { type: GraphQLInt },
forwardParcel: { type: GraphQLInt },
shred: { type: GraphQLInt },
perMonthPerGram: { type: GraphQLInt },
freeStorePerGram: { type: GraphQLInt },
setup: { type: GraphQLInt },
idFree: { type: GraphQLInt }
})
})
})
});
But I'm getting the following errro in GraphiQL
{
"errors": [
{
"message": "The type of Plan.pricing must be Output Type but got: undefined."
}
]
}
Each field in the GraphQLFieldConfigMapThunk or GraphQLFieldConfigMap that you set as your fields must be a GraphQLFieldConfig object that includes properties like type, args, resolve, etc. You cannot set a field to a GraphQLObjectType like you're doing with the pricing field. In other words, your code should look more like this:
const PricingType = new GraphQLObjectType({
name: "Pricing",
fields: () => ({
expires: { type: GraphQLInt },
private: { type: GraphQLBoolean },
monthly: { type: GraphQLInt },
scanEnvelope: { type: GraphQLInt },
initalScan: { type: GraphQLInt },
perPage: { type: GraphQLInt },
forwardMail: { type: GraphQLInt },
forwardParcel: { type: GraphQLInt },
shred: { type: GraphQLInt },
perMonthPerGram: { type: GraphQLInt },
freeStorePerGram: { type: GraphQLInt },
setup: { type: GraphQLInt },
idFree: { type: GraphQLInt }
})
})
const PlanType = new GraphQLObjectType({
name: "Plan",
fields: () => ({
id: { type: GraphQLString },
planName: { type: GraphQLString },
pricing: { type: PricingType },
}),
})

Want to output ID value of user and display it on console

I am using a sailsjs framework for an app. I am building, and I am trying to extract the id value from a model I have:
const memoryCreatorId = _(Memory.creator).map('id').value();
console.log(memoryCreatorId);
const message = {
app_id: '***********************',
contents: {"en": "Yeah Buddy, Rolling Like a Big Shot!"},
filters: [{"field": "tag", "key": "userId", "relation": "=", "value": memoryCreatorId}],
ios_badgeType: 'Increase',
ios_badgeCount: 1
};
return PushNotificationService.sendNotification(message);
I'm basically trying to get what would be the Memory.creator.User.id value. So basically the userid of the person who creates a memory. I'm trying to get it from the "Memory" model "creator" attribute, which maps to the "User" model, and from the "User" model, extract the "id" attribute. Thanks for your help in advance!
Memory model below:
Memory.js
const _ = require('lodash');
module.exports = {
attributes: {
creator: {
model: 'User'
},
title: {
type: 'string'
},
description: {
type: 'text'
},
contentUrl: {
type: 'string',
url: true
},
cropRect: {
type: 'string'
},
likers: {
collection: 'User',
via: 'memoryLikes'
},
comments: {
collection: 'Comment',
via: 'memory'
},
update: {
model: 'Update',
},
cause: {
model: 'Cause',
}
}
};
User model is a follows:
User.js
'use strict';
const uuid = require('node-uuid');
const CipherService = require('../services/CipherService');
const BraintreeService = require('../services/BraintreeService');
module.exports = {
attributes: {
id: {
type: 'string',
primaryKey: true,
defaultsTo: () => uuid.v4(),
unique: true,
index: true,
uuidv4: true
},
firstName: {
type: 'string',
defaultsTo: ''
},
lastName: {
type: 'string',
defaultsTo: ''
},
email: {
type: 'string',
email: true,
required: true,
unique: true
},
password: {
type: 'string'
},
passwordResetToken: {
type: 'string'
},
passwordResetTokenExpires: {
type: 'string'
},
type: {
type: 'string',
enum: ['admin', 'member']
},
city: {
type: 'string'
},
state: {
type: 'string'
},
address: {
type: 'string'
},
institution: {
model: 'Institution'
},
major: {
type: 'string'
},
contentUrl: {
type: 'string',
url: true,
defaultsTo: AwsService.getAssetImageUrl('user-default.png')
},
cropRect: {
type: 'string'
},
graduationYear: {
type: 'integer'
},
donations: {
collection: 'Donation',
via: 'donor'
},
memories: {
collection: 'Memory',
via: 'creator'
},
causes: {
collection: 'Cause',
via: 'followers',
dominant: true
},
adminCauses: {
collection: 'Cause',
via: 'admins'
},
isLeader: {
type: 'boolean',
defaultsTo: false
},
isCurrentStudent: {
type: 'boolean',
defaultsTo: false
},
isAdmin: {
type: 'boolean',
defaultsTo: false
},
adminTitle: {
type: 'string'
},
paymentProfile: {
model: 'PaymentProfile'
},
jsonWebTokens: {
collection: 'Jwt',
via: 'owner'
},
memoryLikes: {
collection: 'Memory',
via: 'likers'
},
updateLikes: {
collection: 'Update',
via: 'likers'
},
toJSON: function() {
return User.clean(this);
}
},
beforeUpdate: (values, next) => {
CipherService.hashPassword(values).then(() => next()).catch(next);
},
beforeCreate: (values, next) => {
CipherService.hashPassword(values).then(() => next()).catch(next);
},
clean: (user) => {
//let obj = user.toObject();
delete user.password;
delete user.jsonWebTokens;
delete user.passwordResetToken;
delete user.passwordResetTokenExpires;
return user;
}
};

Resources