Sending an AlchemyData News query using Node.js (watson-developer-cloud module) - javascript

I'm currently working with Node.js using the watson-developer-cloud Node.js SDK and I'm having problems when sending a query that includes an entity.
This is my code:
// require watson's node sdk and fs
var watson = require('watson-developer-cloud');
var fs = require('fs');
// Define output file
var outputJSONFile = '/home/vagrant/Desktop/node/dir/data.json';
// Create alchemy_data_news object using our api_key
var alchemy_data_news = watson.alchemy_data_news({
api_key: ''
});
// Define params for the query and what values to return
// Accepted returne values:
// docs.alchemyapi.com/v1.0/docs/full-list-of-supported-news-api-fields
var params = {
start: 'now-1m',
end: 'now',
count: 2,
qs: ['q.enriched.url.enrichedTitle.entities.entity.text=apple'],
return: ['enriched.url.url,enriched.url.title']
};
// Call getNews method and return json
alchemy_data_news.getNews(params, function (err, news) {
if (err) {
console.log('error:', err);
} else {
fs.writeFile(outputJSONFile, JSON.stringify(news, null, 2), function(err) {
if (err) {
console.log('WriteFile Error:', err);
} else {
console.log("JSON saved to " + outputJSONFile);
}
});
}
});
I'm still trying to figure out how to send the entities parameters using the params object.
While digging up through some code I came across qs so I have been using that to test but I haven't had success at all.
Any suggestions are greatly appreciated.
P.S: I'm trying to pass:
q.enriched.url.enrichedTitle.entities.entity.text=apple
q.enriched.url.enrichedTitle.entities.entity.type=company

If you look at the node-sdk source code for AlchemyDataNews, you will see that the top level parameters are being sent as query strings.
Then params map should be:
var params = {
start: 'now-1m',
end: 'now',
count: 2,
return: ['enriched.url.url,enriched.url.title'],
// fields here
'q.enriched.url.enrichedTitle.entities.entity.text': 'apple',
'q.enriched.url.enrichedTitle.entities.entity.type': 'company'
};

Related

AWS Kendra sdk call will not return results

I have been following the AWS-Kendra react-search app example you can find here:
https://docs.aws.amazon.com/kendra/latest/dg/deploying.html
After importing the Kendra client with:
const kendra = require('aws-sdk/clients/kendra');
const kendraClient = new kendra({apiVersion: '2019-02-03', region: 'us-east-1'});
Any call on kendraClient to any of the kendra services returns null. I have been executing queries with:
const results = kendraClient.query({ IndexId: INDEX_ID, QueryText: queryText});
Which returns a request object with null data and error fields.
I have calls to S3 which execute correctly in the same file so I do not believe it to be an authentication problem. If I had to guess it's some issue with how I created the kendra object and client, the usual
kendra = new AWS.Kendra();
doesn't work because Kendra is not part of the browser version of the SDK.
Are you trying to run js from browser directly? Here is a sample nodejs code
var kendra = require("aws-sdk/clients/kendra");
var kendraClient = new kendra({apiVersion: "2019-02-03", region: "us-west-2"});
exports.handler = function (event) {
try{
console.log("Starting....");
var params = {
IndexId: "<<Enter your indexId here>>",
QueryText: "<<Enter your queryText here>>",
QueryResultTypeFilter: "DOCUMENT",
PageNumber: 1
};
var kendraResponse = kendraClient.query(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log("Kendra result is", data); // successful response
});
const response = {
"dialogAction":
{
"fulfillmentState":"Fulfilled",
"type":"Close","message":
{
"contentType":"PlainText"
}
}
}
return response;
} catch (error) {
console.log(error)
}
};

Retrieving photo from Azure using Graph API

I'm trying to retrieve a profile picture from the Microsoft Azure API. The code below shows how.
private getProfilePicture(bearerToken: string, tenantId: string): void {
let command = CommandHelper.createRestBlobCommand([
{ name: 'https://graph.microsoft.com/beta'},
{ name: 'me/photo/$value' }
]);
command.Headers.push({ name: 'Authorization', value: 'bearer ' + bearerToken });
// load the photo from graph api.
this._gateway.send(command).subscribe(result => {
let info = result.payload;
var Base64 = require('js-base64').Base64;
var temp = 'data:image/bmp;base64,' + Base64.encode('info');
console.log(temp);
let action = actions.AuthenticationActions.photoLoaded(info);
this._store.dispatch(action);
});
}
The problem however is, that when I look at the output it returns :
data:image/bmp;base64,W29iamVjdCBCbG9iXQ==
Which translates to [object Blob].
My question is how to get the image object here?
with PHP is much simple in nodejs you have to put this to the function who return req as param and do it like this :
app.get('/...', function(req, res){ ...
var base64Data = req.rawBody.replace(/^data:image\/bmp;base64,/, "");
require("fs").writeFile("out.bmp", base64Data, 'base64', function(err) {
console.log(err);
});

Pouchdb database creation no_db_file

I'm trying doing the following: I have a local database (using PouchDB), I check if user is logged in (with pouchdb-authentication login function) and if true I sync the locale db with the remote one.
Unfortunately, when I try to create a new database on CouchDB (I want one db for every user) I always get the error {"error":"not_found","reason":"no_db_file"}. I saw this is a common error described in PouchDB documentation (https://pouchdb.com/guides/databases.html#remote-databases) but CORS is enabled and I can't figure out where is the problem.
My couchdb configuration is:
I do the login as follow:
var user = {
name: 'name',
password: 'password'
};
var url = "http://ip/";
var pouchOpts = {
skipSetup: true
};
var ajaxOpts = {
ajax: {
headers: {
Authorization: 'Basic ' + window.btoa(user.name + ':' + user.password)
}
}
};
var db = new PouchDB(url+'auth', pouchOpts);
db.login(user.name, user.password, ajaxOpts).then(function() {
return db.allDocs();
}).then(function(docs) {
//HERE I TRY TO CREATE THE NEW DATABASE
pouchDBService.sync(url+"newDatabase", user);
}).catch(function(error) {
console.error(error);
});
And, in my pouchDBService I have:
var database;
//I call this function as app starts
this.setDatabase = function(databaseName) {
database = new PouchDB(databaseName, {
adapter: 'websql'
});
}
this.sync = function(remoteDatabase, user) {
var remoteDB = new PouchDB(remoteDatabase, {
auth: {
username: user.name,
password: user.password
},
skip_setup: true //without this I get the login popup! Why if I'm passing the auth params???
});
remoteDB.info().then(function (info) {
console.log(info);
database.sync(remoteDB, {live:true, retry: true})
})
}
Is there something wrong? Any help is appreciated.
Thanks
To create databases on the CouchDB server, you need to be an admin. You could create a small custom API on the server for this (e.g. with a small node http server), or use the couchperuser plugin for CouchDB.

How to convert from JSON to XML

I need to convert some JSON to XML with this library, I need to do that in order to send some data to the Database in a post request I am working on.
This is what req.body returns
{ DealerName: 'amrcl',
CardId: '123',
Nickname: 'mkm123',
Picture: 'http://lorempixel.com/150/150/',
Active: '1',
LegalId: '1',
TypeId: '1'
}
is dynamic data. Let me show you the code
export default function (req, res) {
try {
const connection = new sql.Connection(spConfig, function spConnection (errSpConnection) {
const request = connection.request();
if (errSpConnection) {
res.status(401);
}
request.input('Dealer_Param', sql.VarChar(1000), req.body);
request.input('param_IS_DEBUG', sql.Bit, null);
request.output('output_IS_SUCCESSFUL', sql.Bit);
request.output('output_STATUS', sql.VarChar(500));
request.execute('[mydbo].[StoredProcedure]', function spExecution (errSpExecution, dataset) {
connection.close();
if (errSpExecution) {
res.status(401);
} else {
if (request.parameters.output_IS_SUCCESSFUL.value) {
res.status(200).json({
success : 'New dealer successfully inserted.',
});
}
}
});
});
}
}
that is for Stored Procedure method which is with the mssql module.
As you see the code above, there is a failure error, because in request.input('Dealer_Param', sql.VarChar(1000), req.body); I am sending the JSON I paste at the beginning of the question. But if instead of req.body I put this XML with Dummy data '<Dealers><Detail DealerName = "TESTING123" CardId = "1222" NickName = "tester123" Active = "1" LegalId = "16545" TypeId = "1"></Detail></Dealers>' then everything works fine because the DB need to receive an XML.
So, what are your recommendations, what should I do to put the JSON data as a XML ?
I would just load the json2xml library...
install $ npm install json2xml
import the module in your code: var json2xml = require("json2xml");
and then convert the json to xml like so:
var key,
attrs=[];
for (key in req.body) {
if (req.body.hasOwnProperty(key)) {
var obj = {};
obj.key = req.body.key;
attrs.push(obj);
}
}
var dealerXml = json2xml({dealer:req.body, attr:attrs}, { attributes_key:'attr'});
request.input('Dealer_Param', sql.VarChar(1000), dealerXml);

Javascript nodejs tedious mssql is there a way to get json?

I'm using nodejs and tedious connector to get data from mssql server. In documentation, I only see this one way to retrieve data
var request = new Request("select Name, Value, Article_Id from [tableone] where Id = '1'", function (err, rowCount, rows) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
});
request.on('row', function (rows) {
...
bigArrat.push(JSON.stringify(rows));
});
But in my example I want all rows, not only one property but more. Currently, it return in separate row one cell eg. rows[0].value will return Name, rows[1].value Value ... for me it is rubbish.
I want to get all information in json array of object not all metadata or one property. There is a way to do this or there is a better connector for nodejs and sqlserver ?
The rows value sent to your initial callback is the array of rows being sent back:
var request = new Request("select Name, Value, Article_Id from [tableone] where Id = '1'", function (err, rowCount, rows) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
console.log(rows) // this is the full array of row objects
// it just needs some manipulating
jsonArray = []
rows.forEach(function (columns) {
var rowObject ={};
columns.forEach(function(column) {
rowObject[column.metadata.colName] = column.value;
});
jsonArray.push(rowObject)
});
return callback(null, rowCount, jsonArray);
});
In Sql Server 2016 you can format query results as JSON text using FOR JSON option, see https://msdn.microsoft.com/en-us/library/dn921882.aspx
You just need to read JSON fragments returned by query.
Add this to your config.
rowCollectionOnRequestCompletion: true
var config = {
userName: '', // update me
password: '', // update me
server: '', // update me
options: {
database: '', // update me
encrypt: true,
rowCollectionOnRequestCompletion: true
}
}
Then on your query you can now get the data of rows.
var executeQuery = (res,query) => {
request = new Request(query, (err, rowCount, rows) => {
console.log("Rows: ", rows);
res.send(rows);
});
connection.execSql(request);
}
I learned it from:
http://tediousjs.github.io/tedious/api-request.html
EDIT
Update not to have metadata:
var data = []
request = new Request(query, (err, rowCount, rows) => {
if(err) {
console.log(err)
res.send({ status: 500, data: null, message: "internal server error."})
} else {
console.log(rowCount+' row(s) returned')
res.send({ status: 200, data: data, message: "OK"})
}
})
request.on('row', function(row){
data.push({
last_name: row[0].value,
first_name: row[1].value
})
})
connection.execSql(request)
If you are using express on server side I can recommend using express4-tedious (see https://www.npmjs.com/package/express4-tedious). It allows to easily write apis for SQL connections with small code and streams json result to response.
Connection:
var express = require('express');
var tediousExpress = require('express4-tedious');
var app = express();
app.use(function (req, res, next) {
req.sql = tediousExpress(req, {connection object});
next();
});
Example Api:
/* GET from tableone, streams json result into response */
router.get('/', function (req, res) {
req.sql("select Name, Value, Article_Id from [tableone] where Id = '1' for json path")
.into(res);
});
You can then call these apis e.g. from frontend.
I tried that way but it did not work for me perhaps my knowledge of js and callbacks is not good enough. So, here is my solution. I had to add things to my config of connection to make rows of request work. You would also have to do this. Go to: at the end of new Request section, and to the rows.
here
Second thing, I did is pretty simple.
var jsonArray = [];
var rowObject= {};
var request = new Request("SELECT TOP 5 * FROM tableName",function(err,rowCounts,rows)
{
if (err)
{
console.log(err);
}
else
{
console.log(rowCounts + " rows returned");
}
//Now parse the data from each of the row and populate the array.
for(var i=0; i < rowCounts; i++)
{
var singleRowData = rows[i];
//console.log(singleRowData.length);
for(var j =0; j < singleRowData.length; j++)
{
var tempColName = singleRowData[j].metadata.colName;
var tempColData = singleRowData[j].value;
rowObject[tempColName] = tempColData;
}
jsonArray.push(rowObject);
}
//This line will print the array of JSON object.
console.log(jsonArray);
and to show you how my connection.config looks like:
static config: any =
{
userName: 'username',
password: 'password',
server: 'something.some.some.com',
options: { encrypt: false, database: 'databaseName' ,
rowCollectionOnRequestCompletion: true }
};//End: config
and this is how I am passing it to connection.
static connection = new Connection(Server.config);
Complementing the answer from #Jovan MSFT:
var request = new Request('select person_id, name from person for json path', function(err) {
if (err) {
console.log(err);
}
connection.close();
});
And, finally, in the row event:
request.on('row', function(columns) {
var obj = JSON.parse(columns[0].value);
console.log(obj[0].name);
});
P.S.: the code above does not iterate over columns parameter because for json path returns a single array of objects in a single row and column.
Applying map-reduce function in returned rows:
rows.map(r=>{
return r.reduce((a,k)=>{
a[k.metadata.colName]=k.value
return a
}
,{})
})
This is a combination of a few responses above. This uses FOR JSON AUTO in the SELECT statement and parses the "column" as JSON. The row/column nomenclature may be a bit misleading for folks unfamiliar with this API. In this case, the first "columns" value will be an array of the rows in your table:
var request = new Request("SELECT Name, Value, Article_Id FROM [tableone] WHERE Id = '1' FOR JSON AUTO", function (err, rowCount, rows) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
});
request.on('row', (columns) => {
const json = JSON.parse(columns[0].value);
});

Categories