Accessing Cloudant using nodejs nano - node.js

Is there a gist which I can follow to use to connect to cloudant using nano / nodejs. Or, is there any other library which I can use to connect from nodejs to cloudant. Here is the error I encounter, when i try to connect.
description: 'one of _writer, _creator is required for this request',
Here is how my code looks
// require nano, point it at cloudant's root
var config = require('config');
var nano = require('nano')({url: config.cloudant.url})
, username = config.cloudant.username
, userpass = config.cloudant.password
, cookies = {}
, callback = console.log // this would normally be some callback
;
nano.auth(username, userpass, function (err, body, headers) {
if (err) {
return callback(err);
}
if (headers && headers['set-cookie']) {
cookies['user'] = headers['set-cookie'];
}
callback(null, "it worked");
});
var db = require('nano')({
'url': config.cloudant.url + '/' + config.cloudant.database,
'cookie': cookies['user']
});
After this, when i try to connect - i get the error
var db = require('nano')({
'url': config.cloudant.url + '/' + config.cloudant.database,
'cookie': cookies['user']
});
var doc = {"hello": "world"};
db.insert(doc, function (err, body, headers) {
if (err) {
return callback(err);
}
// change the cookie if couchdb tells us to
if (headers && headers['set-cookie']) {
cookies['user'] = headers['set-cookie'];
}
callback(null, "it worked");
});

You can try using this https://github.com/cloudant/nodejs-cloudant . It is a wrapper over nano to directly connect with cloudant.

Related

Simple fetch from API in Nodejs but UnhandledPromiseRejectionWarning: nestedFunction is not a Function

I'm a non-professional using nodejs server (backend) and javascript/html (frontend) to fetch data from two API's: one API gives a response and I use an ID from the first API to fetch data from the other API. The API returns XML so I use XML2Json and JSON.parse to get the Javascript Object.
everything works perfect until I get to the "return nestedFunction(new_details")-function in the second API-call
so this is where the results are sent back to the client
I do it for the first API and it works fine (backend + frontend)
I tried Async/await but the problem isn't solved
I get the error: "UnhandledPromiseRejectionWarning: TypeError: nestedFunction is not a function"
What could be the problem?
app.get('/AATGetTermMatch', function(req,res) {
let termMatch = req.query.term;
let termLogop = req.query.logop;
let termNotes = req.query.notes;
AATGetTermMatch(termMatch, termLogop, termNotes, function (conceptResults) {
res.send(conceptResults);
});
});
function AATGetTermMatch(termMatch, termLogop, termNotes, nestedFunction) {
let URL = baseURL + "AATGetTermMatch?term=" + termMatch + "&logop=" + termLogop + "&notes=" + termNotes;
fetch(URL)
.then(function (response){
return response.text();
}).then(function (response) {
APICallResults = response;
parseJson();
let objectAPI = JSON.parse(APICallResults);
let full_Concepts = objectAPI.Vocabulary.Subject;
let i;
for (i = 0; i < full_Concepts.length; i++) {
global.ID = full_Concepts[i].Subject_ID;
searchTermDetails(global.ID);
} return nestedFunction(full_Concepts);
});
}
app.get('/subjectID', function(req, res) {
let selectedID = req.query.subjectID;
searchTermDetails(selectedID, function (termDetails) {
res.json(termDetails);
});
});
2nd API : http://vocabsservices.getty.edu/AATService.asmx/AATGetSubject?subjectID=300004838
function searchTermDetails(selectedID, nestedFunction) {
selectedID = global.ID;
let URL_Details = baseURL + "AATGetSubject?" + "subjectID=" + selectedID;
fetch(URL_Details)
.then(function (response) {
return response.text();
}).then(function (response) {
APICallResults_new = response;
parseJsonAgain();
let detailAPI = JSON.parse(APICallResults_new);
let new_details = detailAPI.Vocabulary.Subject;
let Subject_ID = new_details[0].Subject_ID;
let descriptive_Notes_English = new_details[0].Descriptive_Notes[0].Descriptive_Note[0].Note_Text;
} **return nestedFunction(new_details);**
}).catch(function (error) {
console.log("error");
});
}
function parseJson() {
xml2js.parseString(APICallResults, {object: true, trim:true, sanitize: true, arrayNotation: true, mergeAttrs: true}, (err, result) => {
if (err) {
throw err;
}
const resultJson = JSON.stringify(result, null, 4);
//JSON.parse(resultJson);
APICallResults = resultJson;
});
}
function parseJsonAgain() {
xml2js.parseString(APICallResults_new, {object: true, trim:true, sanitize: true, arrayNotation: true, mergeAttrs: true}, (err, result) => {
if (err) {
throw err;
}
const resultJsonAgain = JSON.stringify(result, null, 4);
APICallResults_new = resultJsonAgain;
//console.log(APICallResults_new);
});
}
I've read many threads about this error but the proposed solutions don't seem to work.
In here:
for (i = 0; i < full_Concepts.length; i++) {
global.ID = full_Concepts[i].Subject_ID;
searchTermDetails(global.ID);
}
where you call searchTermDetails(), you are not passing the nestedFunction second argument. Thus, when searchTermDetails() tries to use that argument, it causes the error you get.
You can either add the callback to this call or, if the callback could be optional, then you can modify searchTermDetails to check to see if the second argument is a function and, if not, then don't try to call it.

Moving data from nodejs console to SQL Server

I am very new to node.js. Using the following code I am able to retrive data from the wesbite intrino into console.
var https = require("https");
var username = "********";
var password = "********";
var auth = "Basic " + new Buffer(username + ':' +
password).toString('base64');
var request = https.request({
method: "GET",
host: "api.intrinio.com",
path: "/companies?ticker=AAPL",
headers: {
"Authorization": auth
}
}, function (response) {
var json = "";
response.on('data', function (chunk) {
json += chunk;
});
response.on('end', function () {
var company = JSON.parse(json);
console.log(company);
});
});
request.end();
And the result is as follows:-
My question is: how do I transfer this data into SQL Server? I tried watching a few tutorials and videos. But I was not able to exactly understand how it works.
Thanks in advance.
This is a very broad question. Connecting MS-SQL server from node usually uses tedious package. You can directly use this package to insert data as described in https://learn.microsoft.com/en-us/sql/connect/node-js/step-3-proof-of-concept-connecting-to-sql-using-node-js
Following is a snippet from the above link.
var Connection = require('tedious').Connection;
var config = {
userName: 'yourusername',
password: 'yourpassword',
server: 'yourserver.database.windows.net',
// If you are on Azure SQL Database, you need these next options.
options: {encrypt: true, database: 'AdventureWorks'}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
console.log("Connected");
executeStatement1();
});
var Request = require('tedious').Request
var TYPES = require('tedious').TYPES;
function executeStatement1() {
request = new Request("INSERT SalesLT.Product (Name, ProductNumber, StandardCost, ListPrice, SellStartDate) OUTPUT INSERTED.ProductID VALUES (#Name, #Number, #Cost, #Price, CURRENT_TIMESTAMP);", function(err) {
if (err) {
console.log(err);}
});
request.addParameter('Name', TYPES.NVarChar,'SQL Server Express 2014');
request.addParameter('Number', TYPES.NVarChar , 'SQLEXPRESS2014');
request.addParameter('Cost', TYPES.Int, 11);
request.addParameter('Price', TYPES.Int,11);
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
console.log("Product id of inserted item is " + column.value);
}
});
});
connection.execSql(request);
}
But using an ORM is the best practice. sequelize is one of the best in the node community.
$ npm install --save sequelize
$ npm install --save tedious // MSSQL
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mssql'
});
You must go through either of these modules documentation to understand better.

node.js - page keeps loading - no errors to investigate

this is 1.js
let's run it
node 1.js
and then on the web
execute: domain.tld/-2
it all works perfect.
i see it loaded 2.js and then
used a function to do the mysql query
and displays all the results. perfect.
now on the web let's try to
go to : domain.tld/-3
1.js tries to load 3.js
because the urlpath name is '/-3'
but there is no '3.js'
i am expecting it to say
"page not found'
node 1.js is not crashing.
and web browser is still.. 'loading.."
here is the 1.js :
var http = require('http');
var url = require('url');
var mysql = require('mysql');
var Memcached = require('memcached');
var memcached = new Memcached('localhost:11211');
var connection = mysql.createConnection({
host : '--------------',
user : '2',
password : '-------------',
database : '1'
});
connection.connect();
var server=http.createServer(function(req,res){
res.writeHead(200,{'Content-Type': 'text/html; charset=utf-8'});
var pathname=url.parse(req.url).pathname;
if (pathname.match(/\/-\d{1,2}/)) {
pathname = pathname.replace('-', '')
try{
var o = require('/' + pathname + '.js')
} catch (err){
var o = '0'
}
if (o == '0'){
o = 'page not found'
}else{
o.makeQuery(connection, function(err, result){
if(err) return res.end(err);
o = result;
res.end(o)
});
}
} else if (pathname.match(/^\/$/)) {
res.end('welcome to index page');
} else {
pathname = pathname.replace('/', 'o');
res.end('welcome to user profile page');
}
}).listen(80);
although it may not matter..
here is the 2.js
exports.makeQuery = function(connection, callback) {
var queryString = 'SELECT * FROM 1_accounts order by ac_nu asc limit 5';
connection.query(queryString, function(err,res,fields){
if (err) {return callback(err)};
bb = JSON.stringify(res);
callback(null, bb);
});
}
before i added the following segment to
1.js it was working fine via web.
if (pathname.match(/\/-\d{1,2}/)) {
} else if (pathname.match(/^\/$/)) {
} else {
}
in other words it must have something to do
with those perhaps.
before i added those lines..
it would smoothly display:
"page not found"
You have set o='page not found' but there is no response.write(o) or res.end(o) for it as it is in the else part hence it will never be displayed

Why is PUT request body undefined?

I'm making the following request to my koajs server:
$.ajax({
type : 'PUT', // this.request.body undefined server side
// type : 'POST', // this.request.body all good server side
url : url,
data : body,
dataType : 'json'
})
But on the server side this.request.body is always undefined.
If I change the request type to POST, it works fine.
Any ideas?
EDIT
I'm using koa-route.
EDIT 2
Just realised I'm using koa-body-parser, which is probably more relevant.
Try using the koa-body parser:
const bodyParser = require('koa-bodyparser')
app.use(bodyParser())
I think koa-router will parse typical request stuff, url params, forms etc. If you want to parse the body of a request that contains a JSON object you need to apply a middleware (as alex alluded to).
Also please check to see if you are putting valid JSON.
Take a look at this Koa-bodyparser:
/**
* #param [Object] opts
* - {String} jsonLimit default '1mb'
* - {String} formLimit default '56kb'
* - {string} encoding default 'utf-8'
*/
return function *bodyParser(next) {
if (this.request.body !== undefined) {
return yield* next;
}
if (this.is('json')) {
this.request.body = yield parse.json(this, jsonOpts);
} else if (this.is('urlencoded')) {
this.request.body = yield parse.form(this, formOpts);
} else {
this.request.body = null;
}
yield* next;
};
there looks to be a 1mb limit on the amount of JSON. then to co-body/lib/json.js
module.exports = function(req, opts){
req = req.req || req;
opts = opts || {};
// defaults
var len = req.headers['content-length'];
if (len) opts.length = ~~len;
opts.encoding = opts.encoding || 'utf8';
opts.limit = opts.limit || '1mb';
return function(done){
raw(req, opts, function(err, str){
if (err) return done(err);
try {
done(null, JSON.parse(str));
} catch (err) {
err.status = 400;
err.body = str;
done(err);
}
});
}
};

angularjs error on server callback

I'm making a call to the server using resource and when I go to the base URL of
/viewEvent
It works fine. I receive all the database entries. However, when I go to
/viewEvent/1234
where 1234 is the eventID
I get a undefined is not a function and this is a crash from within angular. Stack trace is
TypeError: undefined is not a function
at copy (http://localhost:8000/js/lib/angular/angular.js:593:21)
at http://localhost:8000/js/lib/angular/angular-resource.js:410:19
at wrappedCallback (http://localhost:8000/js/lib/angular/angular.js:6846:59)
at http://localhost:8000/js/lib/angular/angular.js:6883:26
at Object.Scope.$eval (http://localhost:8000/js/lib/angular/angular.js:8057:28)
at Object.Scope.$digest (http://localhost:8000/js/lib/angular/angular.js:7922:25)
at Object.Scope.$apply (http://localhost:8000/js/lib/angular/angular.js:8143:24)
at done (http://localhost:8000/js/lib/angular/angular.js:9170:20)
at completeRequest (http://localhost:8000/js/lib/angular/angular.js:9333:7)
at XMLHttpRequest.xhr.onreadystatechange (http://localhost:8000/js/lib/angular/angular.js:9303:11) angular.js:575
When I examine the server, the request was made correctly. I can see that it got 1234 and it pulls the correct entry from the mongo database.
This is the controller logic
.controller("viewEventsController", ["$scope", 'EventService', '$location', function($scope, EventService, $location){
var path = $location.path().split('/');
var pathSize = path.length;
$scope.events = [];
if(pathSize === 2){
console.log("No event ID");
$scope.events = EventService.query();
}
else{
console.log("Event ID specified");
EventService.get({"eventID": path[pathSize - 1]}, function(data){
//$scope.events.push(data);
console.log(data);
}, function(error){
console.log(error);
});
}
}]);
and the service logic
service.factory('EventService', function($resource){
return $resource('api/viewEvent/:eventID');
});
It never makes it back to the controller so I'm "confident" it's not that. (watch it be that)
Not sure if the best way, but I got it working by doing
In service:
service.factory('EventService', function($resource){
return $resource('api/viewEvent/:eventID',
{eventID:"#eventID"},
{
'getSingleEvent': {
url: "api/viewEvent/:eventID",
method: "GET",
isArray: true
}
}
);
controller
var path = $location.path().split('/');
var pathSize = path.length;
EventService.getSingleEvent({"eventID":path[pathSize - 1]}, function(result){
$scope.updateEvent();
});
Server
routes = require('./routes')
var router = express.Router();
router.get('/api/viewEvent/:eventID', routes.viewEvent);
and in the routes directory I have a js file with
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'eventApp');
var eventSchema = require('../models/createEvent.js').eventSchema;
var event = db.model('events', eventSchema);
exports.viewEvent = function(req, res){
console.log(req.params.eventID);
if(req.params.eventID) {
event.find({"_id": req.params.eventID}, function (error, events) {
console.log(events);
res.send(events);
});
}
else{
event.find({}, function (error, events) {
console.log(events);
res.send(events);
})
}
};

Resources