Parameter in query graphql breaking JSON with NodeJS - javascript

my script connects to a graphql API by fetch and inserts the JSON return in the postgresql database, however when I insert the primaryLabels parameter into the query, it returns that my JSON is broken by a token>.
If I remove this parameter, everything goes perfectly, any solution?
I tried to turn the query into a string, but the code still fails
Code
let queryAPI = {"query": `{squads {name cards(includedOnKanban: true, closed: false, archived: false, cancelled: false, updatedSince: \"2020-01-01T00:00:00-0300\") { identifier title description status priority assignees { fullname email } secondaryLabel primaryLabels swimlane workstate}}}`};
(async () => {
try {
const rawResponse = await fetch('https://www.bluesight.io/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Bluesight-API-Token': 'token-here'
},
body: JSON.stringify(queryAPI)
});
const content = await rawResponse.json();
OUTPUT
at async C:\Users\Documents\Autoportal\Bluesight\index.js:35:25 {
name: 'FetchError',
message: 'invalid json response body at https://www.bluesight.io/graphql reason: Unexpected token < in JSON at position 0',
type: 'invalid-json'
JSON result example:
{
"data": {
"squads": [
{
"name": "SUPPORT IT",
"cards": [
{
"identifier": "06x38y",
"title": "ALL - Validate data",
"description": "review database.",
"status": null,
"priority": "medium",
"assignees": [
{
"fullname": "Carlos",
"email": "carlos#br.it.com",
}
],
"secondaryLabel": null,
"primaryLabels": [
"CLIENT"
]
}
]
}
]
} }
CONTENT
{
squads: [ { name: 'SUPPORT IT', cards: [Array] } ]
}

Related

Fetching Date Data from DB returns undefined or null

I am willing to pass the dates data from my MongoDB to the antD Date Picker as disabled dates but after fetching the data of date, I get either undefined or null.
What is the approach here?
Below can be seen that my DB has date as a string converted to ISOString, but on fetching it via MongoDB, I get either undefined or null.
My main logic was to pull this date info as response.data.data in frontend after page-loading and passing this data to a useState of setUnavailable date and then assigning this setState to the disableddate function to get a boolean.
Here is my code:
The data in my DB is:
`{
"_id": {
"$oid": "63690afb0623f513b3f22704"
},
"userId": "63614c627330d358d7ceff2d",
"name": "SampleName",
"title": "Doctor",
"type": "Lab Consultation",
"description": "Help Me Please",
"timings": "2022-11-07T06:00:00.000Z",
"date": "2022-11-15T00:00:00.000Z",
"status": "pending",
"createdAt": {
"$date": {
"$numberLong": "1667828475559"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1667828475559"
}
},
"__v": 0
}
`
Schema:
`const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const consultationSchema = new mongoose.Schema(
{
createdBy: {
type: mongoose.ObjectId,
ref: "userModel",
},
userId: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
type: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
timings: {
type: String,
required: true,
},
date: {
type: String,
required: true,
},
status: {
type: String,
required: false,
default: "pending",
},
},
{
timestamps: true,
}
);
const consultationModel = mongoose.model("consultations", consultationSchema);
module.exports = consultationModel;
`
Router Get Data:
`router.get("/get-all-dates", authMiddleware, async (req, res) => {
try {
const consultation = await Consultation.find({
date: { $gte: "2022-11-11T00:00:00.000Z" },
});
const dates = consultation.date;
res.status(200).send({
message: "All Dates Fetched Successfully",
success: true,
data: dates,
});
console.log(dates);
} catch (error) {
console.log(error);
res.status(500).send({
message: "Fetching Dates Failed",
success: false,
error,
});
}
});
`
API Call in React:
`const getDateData = async () => {
try {
dispatch(showLoading());
const response = await axios.get("/api/user/get-all-dates", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
});
dispatch(hideLoading());
if (response.data.success) {
setUnavailableDates(response.data.data);
console.log(response.data.data);
console.log(setUnavailableDates);
}
} catch (error) {
dispatch(hideLoading());
}
};
useEffect(() => {
getDateData();
}, []);
const disabledDate = (current) => {
// How to pass the dates fecthed from DB here? Direct with setUnavailableDates?
return current && current < moment().endOf("day");
};
`
The output in network is this:
`{
"message": "All Dates Fetched Successfully",
"success": true
}`
The output in console is: undefined

Clear database to update content with Notion API

I have a workspace in Notion, which I use to take notes for an app I have on Github.
I want to add a database which will show some download stats from different sources (incuding Github) using the beta Notion API.
Right now I can add information at the end of a database just fine, but I don't understand how to remove the content which was posted before. Or even update it if I can.
This is what I have so far:
import { Client } from "#notionhq/client";
import dotenv from "dotenv";
import { Octokit } from "#octokit/rest";
dotenv.config();
const octokit = new Octokit();
const notion = new Client({ auth: process.env.NOTION_TOKEN });
const databaseId = process.env.NOTION_DATABASE_ID;
async function addEntry(release, name, download_count, tag) {
try {
await notion.request({
path: "pages",
method: "POST",
body: {
parent: { database_id: databaseId },
properties: {
Version: {
title: [
{
text: {
content: release,
},
},
],
},
Name: {
rich_text: [
{
text: {
content: name,
},
},
],
},
"Download Count": {
type: "number",
number: download_count,
},
Tags: {
multi_select: [{ name: "Github" }, { name: tag }],
},
},
},
});
console.log("Success! Entry added.");
} catch (error) {
console.error(error.body);
}
}
(async () => {
const latest_release = await octokit.repos.listReleases({
owner: "ShadowMitia",
repo: "steam_randomiser",
});
const releases = latest_release.data;
let github_downloads = {};
for (let release of releases) {
for (let asset of release.assets) {
console.log(release["tag_name"], asset["name"], asset["download_count"]);
// github_downloads[asset["label"]];
addEntry(
`${release["tag_name"]}`,
`${asset["name"]}`,
asset["download_count"],
asset["name"].includes("linux") ? "Linux" : "Windows"
);
}
}
})();
To delete (archive) a page in a database. Set the archive parameter to true.
curl --location --request PATCH 'https://api.notion.com/v1/pages/YOUR_PAGE_ID' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_BOT_TOKEN' \
--data'{
"parent":{
"database_id":"YOUR_DATABASE_ID"
},
"archived": true,
"properties":{
"Name":{
"title":[
{
"text":{
"content":"A Test Page"
}
}
]
},
"Email": {
"email": "hello#test.com"
},
"multiselect_tags": {
"type": "multi_select",
"multi_select":[{
"name": "Duc Loi Market"
},
{
"name": "Rainbow Grocery"
}]
}
}
}'
To clear data in a page you would set the data to empty or null depending on the property being updated. For example, if you have an array, you would set the property to an empty array.
"multiselect_tags": {
"type": "multi_select",
"multi_select":[ {
"name": "Duc Loi Market"
},
{
"name": "Rainbow Grocery"
}
]
}
}
//Empty a multi_select property
"multiselect_tags": {
"type": "multi_select",
"multi_select":[]
}
If the property is a string, like the email property, set it to null
"Email": {
"email": "hello#test.com"
}
//Empty the value of the email property on a page
"Email": {
"email": null
}

Google People Api: Country not returned in Adresses field

I am trying to get the authenticated user's country by specifying "addresses" field in the People Api request as specified here.
This is the code:
router.post("/test_scope", (req, res) => {
const { idToken, accessToken } = req.body;
authenticationServices
.validateGoogleAccessToken(idToken, accessToken)
.then((response) => {
res.json(response);
});
});
const validateGoogleAccessToken = async (idToken, accessToken) => {
try {
const CLIENT_ID =
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com";
const client = new OAuth2Client(CLIENT_ID);
const ticket = await client.verifyIdToken({
idToken,
audience: CLIENT_ID,
});
const payload = ticket.getPayload();
const { OAuth2 } = google.auth;
const oauth2Client = new OAuth2();
oauth2Client.setCredentials({ access_token: accessToken });
const peopleAPI = google.people({
version: "v1",
auth: oauth2Client,
});
const { data } = await peopleAPI.people.get({
resourceName: "people/me",
personFields: "birthdays,genders,addresses",
});
const { birthdays, genders, addresses, ageRanges } = data;
return data;
} catch (error) {
console.log("error: ", error);
throw new Error("Google token validation failed");
}
};
I have set up the addresses information in the account I am using to sign-in like this:
The is the whole response I get after sending the request:
{
"resourceName": "people/XXXXXXXXXXXXXXXXx",
"etag": "%XXXXXXXXXXXXXXXXXXXXXXXXXX",
"genders": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "XXXXXXXXXXXXXXXXXXXX"
}
},
"value": "female",
"formattedValue": "Female"
}
],
"birthdays": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "1XXXXXXXXXXXXXXXXXXXXXXXX"
}
},
"date": {
"month": 8,
"day": 9
}
},
{
"metadata": {
"source": {
"type": "ACCOUNT",
"id": "XXXXXXXXXXXXXXXXXXXXXXx"
}
},
"date": {
"year": 1996,
"month": 8,
"day": 9
}
}
],
"addresses": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "111110367350060808978"
}
},
"formattedValue": "XXXXXXXXXXXXX, XXXXX, XXXXX",
"type": "home",
"formattedType": "Home"
}
],
}
As you see the country field is missing in "addresses.
NOTE: I am retrieving the idToken and the accessToken from the FrontEnd, after the user clicks on the SignIn button:
import GoogleLogin from "react-google-login";
export class LoginPage extends Component {
onGoogleSignInSucceeded(response) {
const { accessToken, tokenId } = response;
}
render() {
const { errors } = this.state;
return (
<>
<GoogleLogin
clientId="XXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com"
scope="https://www.googleapis.com/auth/user.birthday.read https://www.googleapis.com/auth/user.gender.read https://www.googleapis.com/auth/user.addresses.read"
// IMPORTANT
// https://developers.google.com/people/api/rest/v1/people/get#authorization-scopes
buttonText="Sign-in with your Google account"
onSuccess={this.onGoogleSignInSucceeded}
onFailure={this.onGoogleSignInFailed}
cookiePolicy={"single_host_origin"}
/>
</>
);
}
}
All fields on the address field are optional (see docs). This also includes the country. There is also no guarantee that the data is actually correct (the user can add invalid data to their google profile), so be careful about that and check for the verified metadata (see docs).
That being said you could try using a geocoding API to get the country from the formatted address. This could be made by using a reverse geocoding query (Google Geocoding API documentation).
Also notice that there are other fields that may contain an address. For example locations (see docs) can contain information about where they live.

Ideal way to store multiple texts in mongoose with Node JS?

I've been building a mongoose schema for texts that will be displayed across different pages, and it has end point to POST data for updating the texts.
For example, I would like to store text messages that will be displayed/updated in About Page and Contact Page
What would be the preferred way of designing the text model?
1) Model that has all messages stored in one data object
In front-end, the parent component fetches all text messages with Texts.findOne() and trickles down to pages that need it
const textsSchema = new Schema(
{
aboutMessage1: {
type: String,
required: true
},
aboutMessage2: {
type: String,
required: true
},
contactMessage1: {
type: String
},
contactMessage2: {
type: String
}
},
{ timestamps: true }
);
2) Model that contains each message--so it will have multiple objects
In fron-end, each page uses Text.findById(textId) to retrieve each message
const textSchema = new Schema(
{
// Example: name = contactMessage
name: {
type: String
},
message: {
type: String
}
},
{ timestamps: true }
);
3) Multiple models that contains texts for each page
Similar to 1) approach, texts get fetched with Texts.findOne(), but performed in each page
const aboutTextsSchema = new Schema(
{
message1: {
type: String,
required: true
},
message2: {
type: String,
required: true
},
},
{ timestamps: true }
);
const contactTextsSchema = new Schema(
{
message1: {
type: String,
},
message2: {
type: String,
},
},
{ timestamps: true }
);
The most promising option is the second one. Because first and third options are static, and if in the future, you need to add a new page or or a new message to an existing page, it will require changes in the mongoose model, and deployment for API.
But I think, instead of creating a text schema, it would better to create a page schema for your scenario.
Here I embed messages inside the page schema.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const pageSchema = new Schema(
{
page: {
type: String
},
messages: [
new Schema({
name: {
type: String
},
message: {
type: String
}
})
]
},
{ timestamps: true }
);
module.exports = mongoose.model("Page", pageSchema);
Now we can use this post route to create a page:
router.post("/pages", async (req, res) => {
const result = await Text.create(req.body);
res.send(result);
});
We can create a page and its messages using the previous post route.
Request Body:
{
"_id": "5e4937e9e2454a2c0c162890",
"page": "About",
"messages": [
{
"_id": "5e4937e9e2454a2c0c162892",
"name": "Abou1",
"message": "About1 message..."
},
{
"_id": "5e4937e9e2454a2c0c162891",
"name": "Abou2",
"message": "About2 message..."
}
],
"createdAt": "2020-02-16T12:39:05.154Z",
"updatedAt": "2020-02-16T12:39:05.154Z",
"__v": 0
}
Response:
{
"_id": "5e4937e9e2454a2c0c162890",
"page": "About",
"messages": [
{
"_id": "5e4937e9e2454a2c0c162892",
"name": "Abou1",
"message": "About1 message..."
},
{
"_id": "5e4937e9e2454a2c0c162891",
"name": "Abou2",
"message": "About2 message..."
}
],
"createdAt": "2020-02-16T12:39:05.154Z",
"updatedAt": "2020-02-16T12:39:05.154Z",
"__v": 0
}
If later we want to add a message to a page we can use the following put route.
router.put("/pages/:id", async (req, res) => {
const result = await Page.findByIdAndUpdate(
req.params.id,
{
$push: { messages: req.body }
},
{ new: true }
);
res.send(result);
});
Request Body:
{
"name": "Abou3",
"message": "About3 message..."
}
Response:
{
"_id": "5e4937e9e2454a2c0c162890",
"page": "About",
"messages": [
{
"_id": "5e4937e9e2454a2c0c162892",
"name": "Abou1",
"message": "About1 message..."
},
{
"_id": "5e4937e9e2454a2c0c162891",
"name": "Abou2",
"message": "About2 message..."
},
{
"_id": "5e493926f905ab3300106f94",
"name": "Abou3",
"message": "About3 message..."
}
],
"createdAt": "2020-02-16T12:39:05.154Z",
"updatedAt": "2020-02-16T12:44:22.763Z",
"__v": 0
}
When client needs a page's messages, all we need to do is retrieving the page by it's id or page name:
router.get("/pages/id/:id", async (req, res) => {
const result = await Page.findById(req.params.id);
res.send(result);
});
//or
router.get("/pages/name/:name", async (req, res) => {
const result = await Page.findOne({ page: req.params.name });
res.send(result);
});

How to fetch particular documents in elasticsearch index

I want to fetch all the data of the corresponding particular field, and have a response of the elastic search.
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 35,
"relation": "eq"
},
"max_score": 0.44183275,
"hits": [
{
"_index": "allevents",
"_type": "_doc",
"_id": "jQPDaG0BcOh3oggcguoV",
"_score": 0.44183275,
"_source": {
"category": "sessions",
"contentid": "KqRLj2lWZ3",
"clientname": "omkarpathlab",
------------------
}]
I tried search function it returning an error.
var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
host: 'aaa',
log: 'trace',
apiVersion: '7.1'
});
client.search({
"size": 20,
"query": {
"query_string": {
"default_field": "clientname",
"query": "omkarlab"
}
}
}).then((res) => {
console.log("resultData", res);
}, (err) => {
console.log("err", err);
});
enter code here
Error showing:
{ Error: [illegal_argument_exception] request [/_search] contains unrecognized parameter: [query]
Please suggest me how to solve this kind of problem.
You should specify your field under default_field, not the value you are looking for. The field you are trying to query is clientname in your case, and the value you are looking for is omkarpathlab. So your query should be as follows:
"query": {
"query_string": {
"default_field": "clientname",
"query": "omkarpathlab"
}
}
edit. But your query inside of the body property:
client.search({
"size": 20,
"body": {
"query": {
"query_string": {
"default_field": "clientname",
"query": "omkarlab"
}
}
}
}).then((res) => {
console.log("resultData", res);
}, (err) => {
console.log("err", err);
});
You can use below code to connect to elasticsearch. I have tested it on 5.6 version
'use strict'
const { Client } = require('#elastic/elasticsearch')
const client = new Client({ node: 'http://XXX:9200' })
async function run () {
// Let's search!
const { body } = await client.search({
index: 'XXX',
type : 'XXX',
body: {
query: {
match_all: {}
}
}
})
console.log(body.hits.hits)
}
run().catch(console.log)
Code is a sample from https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/search_examples.html site.
for search documentation check below link
https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#_search

Categories

Resources