CouchDB document update handler truncating URL parameters, despite example from documentation - couchdb

According to the documents here: https://wiki.apache.org/couchdb/Document_Update_Handlers#Request
I can specify an update handler that accepts query string parameters. eg. (straight from the docs):
handlerName: function(doc, req) {
var field = req.query.field;
var value = req.query.value;
var message = 'set ' + field + ' to ' + value;
doc[field] = value;
return [doc, message];
}
However when I look at the req object, there is no query.value field. My cURL command looks like this:
curl -X PUT http://127.0.0.1:5984/map_reduce2/_design/mp2/_update/test/1?field=THEFIELD&value=THEVALUE
And the resultant document looks like this:
{
"_id": "1",
"_rev": "24-06f05b375e4da9ec2fc88e28711fff7d",
"x": {
"info": {
"db_name": "map_reduce2",
"doc_count": 30,
"doc_del_count": 4,
"update_seq": 168,
"purge_seq": 0,
"compact_running": false,
"disk_size": 970856,
"data_size": 187724,
"instance_start_time": "1461749557106546",
"disk_format_version": 6,
"committed_update_seq": 168
},
"id": "1",
"uuid": "cb9251557f16b50c26ef2abd8200a727",
"method": "PUT",
"requested_path": [
"map_reduce2",
"_design",
"mp2",
"_update",
"test",
"1?field=THEFIELD"
],
"path": [
"map_reduce2",
"_design",
"mp2",
"_update",
"test",
"1"
],
"raw_path": "/map_reduce2/_design/mp2/_update/test/1?field=THEFIELD",
"query": {
"field": "THEFIELD"
},
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1:5984",
"User-Agent": "curl/7.43.0"
},
"body": "undefined",
"peer": "127.0.0.1",
"form": {
},
"cookie": {
},
"userCtx": {
"db": "map_reduce2",
"name": null,
"roles": [
]
},
"secObj": {
}
}
}

Related

What is wrong with this javascript regex string.replace?

UPDATE: I've discovered this problem is because of the "stringified" output which contains no spaces or newlines and is different than the original JSON.
Stringified output:
{"eventType":"Delivery","mail":{"timestamp":"2021-08-09T20:41:51.515Z","source":"removed#email.com","sourceArn":"arn:aws:ses:us-east-1:1234567890:identity/removed.com","sendingAccountId":"1234567890","messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","destination":["removedl#email.com"],"headersTruncated":false,"headers":[{"name":"From","value":"removed#email.com"},{"name":"To","value":"removed#email.com"},{"name":"Subject","value":"Test"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"7bit"}],"commonHeaders":{"from":["removed#email.com"],"to":["removed#email.com"],"messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","subject":"Test"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["GenericLog"],"ses:source-ip":["123.123.123.123"],"ses:from-domain":["email.com"],"ses:caller-identity":["user1"],"ses:outgoing-ip":["234.234.234.234"]}},"delivery":{"timestamp":"2021-08-09T20:41:52.880Z","processingTimeMillis":1365,"recipients":["removed#email.com"],"smtpResponse":"250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b#email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery","reportingMTA":"a48-108.smtp-out.amazonses.com"}}
ORIGINAL:
I want to remove the : from the key names and replace it with a _ in the following JSON. (In the tags section)
{
"eventType": "Delivery",
"mail": {
"timestamp": "2021-08-09T20:41:51.515Z",
"source": "removed#email.com",
"sourceArn": "arn:aws:ses:us-east-1:1234567890:identity/removed.com",
"sendingAccountId": "1234567890",
"messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b",
"destination": [
"removedl#email.com"
],
"headersTruncated": false,
"headers": [
{
"name": "From",
"value": "removed#email.com"
},
{
"name": "To",
"value": "removed#email.com"
},
{
"name": "Subject",
"value": "Test"
},
{
"name": "MIME-Version",
"value": "1.0"
},
{
"name": "Content-Type",
"value": "text/plain; charset=UTF-8"
},
{
"name": "Content-Transfer-Encoding",
"value": "7bit"
}
],
"commonHeaders": {
"from": [
"removed#email.com"
],
"to": [
"removed#email.com"
],
"messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b",
"subject": "Test"
},
"tags": {
"ses:operation": [
"SendEmail"
],
"ses:configuration-set": [
"GenericLog"
],
"ses:source-ip": [
"123.123.123.123"
],
"ses:from-domain": [
"email.com"
],
"ses:caller-identity": [
"user1"
],
"ses:outgoing-ip": [
"234.234.234.234"
]
}
},
"delivery": {
"timestamp": "2021-08-09T20:41:52.880Z",
"processingTimeMillis": 1365,
"recipients": [
"removed#email.com"
],
"smtpResponse": "250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b#email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery",
"reportingMTA": "a48-108.smtp-out.amazonses.com"
}
}
I've created a node.js Lambda function that is being called by AWS Kinesis. It processes the above JSON and the following code is being used. I am debugging, so I am simply trying to search and replace the string for testing:
console.log('Loading function');
exports.handler = async (payload, context) => {
payload = JSON.stringify(payload);
payload = payload.replace(/".*:.*":/g, 'replaced');
console.log('Replaced payload:', payload);
};
I've run the regex through multiple code testing sites and it correctly identifies all 6 occurrences of the key names with a : in them. I've even used this tester, and it correctly replaces all 6 strings as expected. But, when it runs on Lambda I get the following output:
Replaced payload: {replaced"a48-108.smtp-out.amazonses.com"}}
Am I missing something obvious or is this some weird thing happening in Lambda?
Note, if I simply output the unmodified payload variable it matches the input JSON, so that is not the issue.
I've got additional code which should complete this task successfully once I solve this mystery. But, if you could provide the code to replace : with _ in the key names, that would be great as well.
Expanding on your update comment:
UPDATE: I've discovered this problem is because of the "stringified" output which contains no spaces or newlines and is different than the original JSON.
You can add the following options to JSON.stringify to properly format the stringified output.
JSON.stringify(payload, null, 4);
Demo:
let payload = {"eventType":"Delivery","mail":{"timestamp":"2021-08-09T20:41:51.515Z","source":"removed#email.com","sourceArn":"arn:aws:ses:us-east-1:1234567890:identity/removed.com","sendingAccountId":"1234567890","messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","destination":["removedl#email.com"],"headersTruncated":false,"headers":[{"name":"From","value":"removed#email.com"},{"name":"To","value":"removed#email.com"},{"name":"Subject","value":"Test"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"7bit"}],"commonHeaders":{"from":["removed#email.com"],"to":["removed#email.com"],"messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","subject":"Test"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["GenericLog"],"ses:source-ip":["123.123.123.123"],"ses:from-domain":["email.com"],"ses:caller-identity":["user1"],"ses:outgoing-ip":["234.234.234.234"]}},"delivery":{"timestamp":"2021-08-09T20:41:52.880Z","processingTimeMillis":1365,"recipients":["removed#email.com"],"smtpResponse":"250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b#email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery","reportingMTA":"a48-108.smtp-out.amazonses.com"}};
payload = JSON.stringify(payload, null, 4)
payload = payload.replace(/".*:.*":/g, 'replaced');
console.log('Replaced payload:', payload);
Mind that simply using .* means "as many characters as you can match", i.e. it's eager. You can add a ? for lazy matching, as in "match as few as possible".
I suggest using /".*?:.*?":/g since this basically means "get all characters to the closest : and then the characters to the closest ":".
Using a recursive function to map the object instead of using a RegExp on the JSON version:
const data = { "eventType": "Delivery", "mail": { "timestamp": "2021-08-09T20:41:51.515Z", "source": "removed#email.com", "sourceArn": "arn:aws:ses:us-east-1:1234567890:identity/removed.com", "sendingAccountId": "1234567890", "messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b", "destination": ["removedl#email.com"], "headersTruncated": false, "headers": [{ "name": "From", "value": "removed#email.com" }, { "name": "To", "value": "removed#email.com" }, { "name": "Subject", "value": "Test" }, { "name": "MIME-Version", "value": "1.0" }, { "name": "Content-Type", "value": "text/plain; charset=UTF-8" }, { "name": "Content-Transfer-Encoding", "value": "7bit" }], "commonHeaders": { "from": ["removed#email.com"], "to": ["removed#email.com"], "messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b", "subject": "Test" }, "tags": { "ses:operation": ["SendEmail"], "ses:configuration-set": ["GenericLog"], "ses:source-ip": ["123.123.123.123"], "ses:from-domain": ["email.com"], "ses:caller-identity": ["user1"], "ses:outgoing-ip": ["234.234.234.234"] } }, "delivery": { "timestamp": "2021-08-09T20:41:52.880Z", "processingTimeMillis": 1365, "recipients": ["removed#email.com"], "smtpResponse": "250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b#email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery", "reportingMTA": "a48-108.smtp-out.amazonses.com" } };
function convert(obj) {
if (typeof obj !== 'object') return obj;
if (Array.isArray(obj)) return obj.map(convert);
const result = {};
for(const key in obj) {
result[key.replace(/:/g, '_')] = convert(obj[key]);
}
return result;
}
const converted = convert(data);
console.log(converted);
console.log(JSON.stringify(converted, null, 4));

ElasticSearch query works on dev console but fails in NodeJS instance

I have the following ElasticSearch query that used to retrieve a bunch of pages (search) paginated using a cursor offset.
Query
GET _search
{
"search_after": [
1.8574909,
"urn:sample/78PsC1EHG6nopQCA/n/749d1ed1-d08d-44a1-abac-9ebad8c76697"
],
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"_id": {
"order": "asc"
}
}
],
"size": 1,
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"type": "node"
}
},
{
"query_string": {
"query": "a",
"fields": [
"node.text.string",
"node.text.string.english"
]
}
}
]
}
}
]
}
}
],
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"workspace.type": "space"
}
},
{
"terms": {
"workspace.id": [
"72MsGpeV9zGu5ytZ"
]
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"workspace.type": "user"
}
},
{
"term": {
"workspace.id": "8"
}
}
]
}
}
]
}
}
}
},
"highlight": {
"fields": {
"comment.body.text": {},
"comment.body.text.english": {},
"node.text.string": {},
"node.text.string.english": {}
}
}
}
The query works fine in the dev console and returns a hit with an edge.
Result
{
"took" : 136,
"timed_out" : false,
"num_reduce_phases" : 2,
"_shards" : {
"total" : 929,
"successful" : 929,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : null,
"hits" : [
{
"_index" : "sample-development-john",
"_type" : "_doc",
"_id" : "urn:sample:d/78PsC1EHG6nopQCA/n/4230ca5a-5e1e-48ee-a70f-95f7b2d09995",
"_score" : 1.7747711,
"_source" : {
"document_id" : "78PsC1EHG6nopQCA",
"type" : "node",
"workspace" : {
"type" : "space",
...
However, performing the same query through my NodeJS resolver using the Javascript ES API fails when I copy the exact same query in my code.
SearchResolver.js
// parse the cursor argument for pagination.
search_after = JSON.parse(Buffer.from(args.after, 'base64').toString('ascii'));
const response: ApiResponse<Taskade.Backend.Elasticsearch.SearchBody> = await client.search({
index,
body: {
search_after: [
1.8574909,
'urn:taskade:d/78PsC1EHG6nopQCA/n/749d1ed1-d08d-44a1-abac-9ebad8c76697',
],
sort: [
{
_score: {
order: 'desc',
},
},
{
_id: {
order: 'asc',
},
},
],
size: 1,
query: {
bool: {
must: [
{
bool: {
should: [
{
bool: {
must: [
{
term: {
type: 'node',
},
},
{
query_string: {
query: 'a',
fields: ['node.text.string', 'node.text.string.english'],
},
},
],
},
},
],
},
},
],
filter: {
bool: {
should: [
{
bool: {
must: [
{
term: {
'workspace.type': 'space',
},
},
{
terms: {
'workspace.id': ['72MsGpeV9zGu5ytZ'],
},
},
],
},
},
{
bool: {
must: [
{
term: {
'workspace.type': 'user',
},
},
{
term: {
'workspace.id': '8',
},
},
],
},
},
],
},
},
},
},
highlight: {
fields: {
'comment.body.text': {},
'comment.body.text.english': {},
'node.text.string': {},
'node.text.string.english': {},
},
},
},
}
Error
{
"errors": [
{
"message": "parsing_exception",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"search"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"name": "ResponseError",
"meta": {
"body": {
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "Unknown key for a VALUE_STRING in [query].",
"line": 1,
"col": 10
}
],
"type": "parsing_exception",
"reason": "Unknown key for a VALUE_STRING in [query].",
"line": 1,
"col": 10
},
"status": 400
},
"statusCode": 400,
"headers": {
"date": "Mon, 28 Dec 2020 11:58:05 GMT",
"content-type": "application/json; charset=UTF-8",
"content-length": "239",
"connection": "keep-alive",
"access-control-allow-origin": "*"
},
"warnings": null,
"meta": {
"context": null,
"request": {
"params": {
"method": "POST",
"path": "/sample-development-john/_search",
"body": "{\"query\":\"a\",\"size\":1,\"sort\":[{\"_score\":{\"order\":\"asc\"}},{\"_id\":{\"order\":\"desc\"}}],\"search_after\":[1.7747711,\"urn:sample:d/78PsC1EHG6nopQCA/n/4230ca5a-5e1e-48ee-a70f-95f7b2d09995\"]}",
"querystring": "",
"headers": {
"User-Agent": "elasticsearch-js/6.8.7 (darwin 20.2.0-x64; Node.js v10.21.0)",
"Content-Type": "application/json",
"Content-Length": "182"
},
"timeout": 30000
},
"options": {
"warnings": null
},
"id": 2
},
"name": "elasticsearch-js",
"connection": {
"url": "https://search-sample-dev-526nv5wyqxj6ahzcql2cyndz5e.us-east-1.es.amazonaws.com/",
"id": "https://search-sample-dev-526nv5wyqxj6ahzcql2cyndz5e.us-east-1.es.amazonaws.com/",
"headers": {},
"deadCount": 0,
"resurrectTimeout": 0,
"_openRequests": 0,
"status": "alive",
"roles": {
"master": true,
"data": true,
"ingest": true,
"ml": false
}
},
"attempts": 0,
"aborted": false
}
},
"stacktrace": [
"ResponseError: parsing_exception",
" at IncomingMessage.response.on (/Users/john/dev/sample/ft/node_modules/#elastic/elasticsearch/lib/Transport.js:296:25)",
" at IncomingMessage.emit (events.js:203:15)",
" at IncomingMessage.EventEmitter.emit (domain.js:466:23)",
" at endReadableNT (_stream_readable.js:1145:12)",
" at process._tickCallback (internal/process/next_tick.js:63:19)"
]
}
}
}
],
"data": {
"search": null
}
}
This error occurs when I pass the after (search_after) parameter to my GraphQL call, despite the values for the query all being hardcoded (including search_after as seen in the first Query snippet).
// query will work if `after` is not passed. The values here don't matter since for testing purposes, all values are hardcoded in the resolver.
query {
search(after: "WzEuODU3NDkwOSwidXJuOnRhc2thZGU6ZC83OFBzQzFFSEc2bm9wUUNBL24vNzQ5ZDFlZDEtZDA4ZC00NGExLWFiYWMtOWViYWQ4Yzc2Njk3Il0=", first:1, filterby:{query:"a"}){
edges{
cursor
node {
...
Why is the query working in the dev console, but not working in my resolver when I pass the after (search_after after parsing the JSON) params to the GQL call despite the query being hardcoded and identically similar.

How to fetch single matched document from nested array mongodb?

I have nested array object in my MongoDB document, but the predicate is not return as expected, which in this case I only want matched document only.
Document Structure
{
"_id": {
"$oid": "5fddb34848be35283c36955b"
},
"projectId": {
"$oid": "5fddb30d48be35283c36955a"
},
"urls": [
{
"_id": {
"$oid": "5fddb34848be35283c36955c"
},
"group": "User",
"data": [
{
"option": {
"applyDifferentContentType": false,
"allowInjection": false
},
"_id": {
"$oid": "5fddad1e48be35283c369558"
},
"url": "/users/create",
"method": "patch",
"headers": {
"Content-Type": "multipart/form-data"
}
},
{
"option": {
"applyDifferentContentType": false,
"allowInjection": false
},
"_id": {
"$oid": "5fddad1e48be35283c369558"
},
"url": "/users/update",
"method": "post",
"headers": {
"Content-Type": "application/json"
}
},
{
"option": {
"applyDifferentContentType": false,
"allowInjection": false
},
"_id": {
"$oid": "5fddad1e48be35283c369558"
},
"url": "/users/delete",
"method": "post",
"headers": {
"Content-Type": "application/json"
}
}
]
},
{
"_id": {
"$oid": "5fddb34f48be35283c36955d"
},
"group": "Project",
"data": [
{
"option": {
"applyDifferentContentType": true,
"allowInjection": false
},
"_id": {
"$oid": "5fddad1e48be35283c369558"
},
"url": "/project/create",
"method": "post",
"headers": {
"Content-Type": "application/json"
}
},
{
"option": {
"applyDifferentContentType": false,
"allowInjection": false
},
"_id": {
"$oid": "5fddad1e48be35283c369558"
},
"url": "/projects/update",
"method": "post",
"headers": {
"Content-Type": "application/url-encoded"
}
}
]
},
{
"_id": {
"$oid": "5fddb37d48be35283c36955e"
},
"group": "Contact",
"data": [
{
"option": {
"applyDifferentContentType": false,
"allowInjection": false
},
"_id": {
"$oid": "5fddad1e48be35283c369558"
},
"url": "/contact/create",
"method": "post",
"headers": {
"Content-Type": "multipart/form-data"
}
}
]
}
],
"__v": 0 }
Fetch Query
const result = await URLPayload.find({
"projectId": projectId,
"urls.data": {
$elemMatch: {
"_id": dataId
}
}
})
.lean();
projectId => 5fddb30d48be35283c36955a
dataId => 5fddad1e48be35283c369558
But above predicate is not giving expected result.
How to return only matched single document from nested array object ?
I have nested array object in my MongoDB document, but the predicate is not return as expected, which in this case I only want matched document only.
You can use aggregation pipeline,
make your you have to convert projectId and dataId input fields string type to object type using mongoose.Types.ObjectId
$match your conditions,
$project to show required documents
$reduce to iterate loop of urls array
$filter to iterate loop of urls.data array and filter matching _id,
$first will return object from the array, you can use $arrayElemAt instead of $first for older version of MongoDB
const result = await URLPayload.aggregate([
{
$match: {
projectId: mongoose.Types.ObjectId(projectId),
"urls.data._id": mongoose.Types.ObjectId(dataId)
}
},
{
$project: {
urlData: {
$reduce: {
input: "$urls",
initialValue: {},
in: {
$first: {
$filter: {
input: "$$this.data",
cond: { $eq: ["$$this._id", mongoose.Types.ObjectId(dataId)] }
}
}
}
}
}
}
}
])
Playground
I'm not used working with $oid inside the _id element but this should work.
const ids = {
projectId: "5fddb30d48be35283c36955a",
urlId: "5fddb34848be35283c36955c",
dataId: "5fddad1e48be35283c369558"
}
await URLPayload.findOne({ "projectId.$oid": ids.projectId },
{
"$elemMatch": { "urls.$[url].data": { "_id.$oid": ids.dataId } }
}, {
"arrayFilters": [
{ "url._id.$oid": ids.urlId }
]
}, (err, urlPayloadResult) => {
if (err) {
console.log(err)
} else {
console.log({ message: urlPayloadResult })
}
})
If not work in your case just remove the ".$oid" element.
Let me know if this work.

How to get valid JSON response from axios library using nodeJS

I'm trying to hit the REST endpoint by using AXIOS library and the response.data return the below in console.log:
Reseponse for console.log(response.data)
{
sqlQuery: "select type,subtype from wetrade_p2 where parent_id='69341269'",
message: '1 rows selected',
row: [ { column: [Array] } ]
}
But when I hit the same REST endpoint in postman and I can get the entire Response JSON as like below:
PostMan Output (Expected):
{
"sqlQuery": "select type,subtype from wetrade_p2 where parent_id='69341269'",
"message": "2 rows selected",
"row": [
{
"column": [
{
"value": "W",
"name": "TYPE"
},
{
"value": "P",
"name": "STATUS"
},
{
"value": "0",
"name": "SUBTYPE"
},
{
"value": "USD",
"name": "CURRENCY"
}
]
},
{
"column": [
{
"value": "W",
"name": "TYPE"
},
{
"value": "S",
"name": "STATUS"
},
{
"value": "0",
"name": "SUBTYPE"
},
{
"value": "USD",
"name": "CURRENCY"
}
]
}
]
}
I also tried to stingify the response.data and it returned below response which is not able to parse()
Getting below response in console.log when I tried to use JSON.stringify(response.data):
sqlQuery: "select type,subtype from wetrade_p2 where parent_id=69341269"
message: "2 rows selected"
row: [
{
"column": [
{
"value": "W",
"name": "TYPE"
},
{
"value": "P",
"name": "STATUS"
},
{
"value": "0",
"name": "SUBTYPE"
},
{
"value": "USD",
"name": "CURRENCY"
}
]
},
{
"column": [
{
"value": "W",
"name": "TYPE"
},
{
"value": "S",
"name": "STATUS"
},
{
"value": "0",
"name": "SUBTYPE"
},
{
"value": "USD",
"name": "CURRENCY"
}
]
}
]
Sample Code:
await axios[methodType](url, body, {
httpsAgent:httpsAgent,
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Access-Control-Allow-Origin": true
}
}).then(response => {
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log(response.data);
console.log(JSON.stringify(response.data))
console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
console.log(response);
}).catch(error => {
console.log(error);
});
You DO get the right data, just node.js doesn't display it in the console/stdout. You can use util.inspect() for a better formatted output. Try this:
const util = require('util');
// ...
console.log(util.inspect(response.data, { showHidden: false, depth: null }));

New to Node and having trouble with the Youtube Data API

Using Node.js for the first time and working with the Youtube Data API. I can't quite get the data I want from the API when I make a request to it. This is what the data coming back from the API is supposed to look like:
/**
* API response
*/
{
"kind": "youtube#commentThreadListResponse",
"etag": "\"VPWTmrH7dFmi4s1RqrK4tLejnRI/yVL3QyyDwJFkFNOcCd4KZCcTFDw\"",
"nextPageToken": "QURTSl9pMlQySG1zcHRKb0dNZ3dWdlYtcUhyRDFDVlJXaHFmdVFiMUlaUFJfTTNjdTFpQzFNWUNuWjhBY0d2ZV8tTGR2aHFXRXRJVDZRQVpRM0YzNndWVXlQVFNwOU94UVFCWVd2empIVUlGdHlFR25keU8=",
"pageInfo": {
"totalResults": 20,
"resultsPerPage": 20
},
"items": [
{
"kind": "youtube#commentThread",
"etag": "\"VPWTmrH7dFmi4s1RqrK4tLejnRI/OqxtT8nFAjcFFrHa4DbZrY_NItM\"",
"id": "z13bwzmokuzcxtcqn04cclqbiozixldh21o"
},
{
"kind": "youtube#commentThread",
"etag": "\"VPWTmrH7dFmi4s1RqrK4tLejnRI/1B_usKd_ZpCLxG5l5nL7QfUtG3o\"",
"id": "z13puhijunbzytdcn22lstwptmybyzwdl"
},
{
"kind": "youtube#commentThread",
"etag": "\"VPWTmrH7dFmi4s1RqrK4tLejnRI/h8sS5KTOFa7CQWU5Je2Fp5UQ0bk\"",
"id": "z13dfbwzjyrpiznqc04cgjlpbyn0wtaiqpw0k"
},
{
"kind": "youtube#commentThread",
"etag": "\"VPWTmrH7dFmi4s1RqrK4tLejnRI/FQEl6XU95FHiM1ijRxC5fqngmqk\"",
"id": "z12atro51wfhzvmp104cihfytveyshbr4s40k"
},
{ ...........AND SO ON
I then use the following code in an attempt to console.log() this data from the youtube API
var DATABASE = youtube.commentThreads.list(
{ 'videoId': '7YcW25PHnAA', 'part': 'id, replies'}, function(err, data){
if(err){
console.error('Error: ' + err);
}
});
var resp = JSON.stringify(DATABASE);
console.log(resp);
But this is my output instead:
{
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "www.googleapis.com",
"port": null,
"hostname": "www.googleapis.com",
"hash": null,
"search": "?videoId=7YcW25PHnAA&part=id%2C%20replies&key=AIzaSyDTTnj4HncXQCM3U-9XUvHyIf7kE9f2ZUk",
"query": "videoId=7YcW25PHnAA&part=id%2C%20replies&key=AIzaSyDTTnj4HncXQCM3U-9XUvHyIf7kE9f2ZUk",
"pathname": "/youtube/v3/commentThreads",
"path": "/youtube/v3/commentThreads?videoId=7YcW25PHnAA&part=id%2C%20replies&key=AIzaSyDTTnj4HncXQCM3U-9XUvHyIf7kE9f2ZUk",
"href": "https://www.googleapis.com/youtube/v3/commentThreads?videoId=7YcW25PHnAA&part=id%2C%20replies&key=AIzaSyDTTnj4HncXQCM3U-9XUvHyIf7kE9f2ZUk"
},
"method": "GET",
"headers": {
"User-Agent": "google-api-nodejs-client/0.10.0",
"host": "www.googleapis.com",
"accept": "application/json"
}

Resources