Examples and documentation for couchnode - node.js

I am trying to integrate couchbase into my NodeJS application with couchnode module. Looks like it lacks of documentation. I see a lot of methods with parameters there in the source code but I can't find much information about how they work. Could you please share me with some, may be examples of code? Or should I read about these methods from other languages' documentation as there are chances they are the same?

To make development easier, I wrote a little helper (lib/couchbase.js):
var cb = require('couchbase'),
config;
if(process.env.NODE_ENV === 'production') {
config = require('../lib/config');
} else {
config = require('../lib/localconfig');
}
module.exports = function(bucket, callback) {
config.couchbase.bucket = bucket;
cb.connect(config.couchbase, callback);
};
Here's some example code for a view and async/each get operation. Instead of 'default' you can use different buckets.
var couchbase = require('../lib/couchbase');
couchbase('default', function(error, cb) {
cb.view('doc', 'view', {
stale: false
}, function(error, docs) {
async.each(docs, function(doc, fn) {
cb.get(doc.id, function(error, info) {
// do something
fn();
}
}, function(errors) {
// do something
});
});
});

I adapted an AngularJS and Node.js web application that another developer wrote for querying and editing Microsoft Azure DocumentDB documents to let it work with Couchbase:
https://github.com/rrutt/cb-bread
Here is the specific Node.js module that performs all the calls to the Couchbase Node SDK version 2.0.x:
https://github.com/rrutt/cb-bread/blob/dev/api/lib/couchbaseWrapper.js
Hopefully this provides some help in understanding how to configure arguments for many of the Couchbase API methods.

Related

How do I add parameters to long-form return requests in module.exports routes?

I'm coding for an API connection area, that's predominately graphql but needs to have some REST connections for certain things, and have equivalent to the following code:
foo.js
module.exports = {
routes: () => {
return [
{
method: 'GET',
path: '/existing_endpoint',
handler: module.exports.existing_endpoint
},
{
method: 'POST',
path: '/new_endpoint',
handler: module.exports.new_endpoint // <--- this not passing variables
}
]
},
existing_endpoint: async () => {
/* endpoint that isn't the concern of this */
},
new_endpoint: async (req, res) => {
console.log({req, res})
return 1
}
}
The existing GET endpoint works fine, but my POST endpoint always errors out with the console of {} where {req, res} should have been passed in by the router, I suspect because the POST isn't receiving. I've tried changing the POST declaration in the routes to module.exports.new_endpoint(req, res), but it tells me the variables aren't found, and the lead-in server.js does have the file (it looks more like this...), and doing similar with the server.js, also getting similar results, implying that's probably wrong too. Also, we have a really strict eslint setup, so I can't really change the format of the call.
Every example I've seen online using these libraries is some short form, or includes the function in the routes call, and isn't some long form like this. How do I do a POST in this format?
/* hapi, environment variables, apollog server, log engine, etc. */
/* preceeding library inclusions */
const foo = require('./routes/foo')
const other_route = require('./routes/other_route')
const startServer = async () => {
const server = Hapi.server({port, host})
server.route(other_route.routes())
server.route(foo.routes())
}
This is a bug with Hapi in node v16. I just opened an issue.
Your current solutions are either:
Upgrade to Hapi v20
Use n or another method to downgrade to node v14.16 for this project. I can confirm that POST requests do not hang in this version.

How to call Hapi plugin function from another

In Hapi (v17 if it makes any difference), what is the correct way to call a function in a plugin from another ?
Let's say I've started writing a wrapper plugin around Nodemailer :
'use strict';
const Nodemailer = require('nodemailer');
exports.plugin = {
name: 'mailerWrapperPlugin',
version: '0.0.1',
register: async function (server, options) {
}
};
What would be the correct way to expose plugin functions elsewhere in Hapi (i.e to the Hapi instance itself, but perhaps more importantly, to other plugins loaded by Hapi).
I'm finding the Hapi documentation a bit sparse, especially in relation to plugins.
So, for example, if my Nodemailer wrapper had a sendMail() function, how would I make that available in another plugin I've written ?
P.S. I'm a bit of a Node.JS/Hapi newbie, so treat me gently ! I'm testing this out because I'm thinking of migrating from PHP to Hapi for future backend applications.
You can use server.methods object. The doc says:
Server methods are functions registered with the server and used
throughout the application as a common utility. Their advantage is in
the ability to configure them to use the built-in cache and share
across multiple request handlers without having to create a common
module.
Now this is your first plugin:
const Nodemailer = require('nodemailer');
exports.plugin = {
name: 'mailerWrapperPlugin',
version: '0.0.1',
register: async function (server, options) {
server.method('sendMail', (subject, to, body) => {
// compose and send mail here
});
}
};
and this is your second, and make sure this is loaded after the first one.
exports.plugin = {
name: 'anotherPlugin',
version: '0.0.1',
register: async function (server, options) {
server.methods.sendMail("Hello", "test#test.com", "Sup?");
}
};
That's it.
Also you can use server.decorate object as well. Its doc says:
Extends various framework interfaces with custom methods where:
server.decorate may add methods to several other objects like routes, request, server and response object.
If we go back to your plugin:
exports.plugin = {
name: 'mailerWrapperPlugin',
version: '0.0.1',
register: async function (server, options) {
server.decorate('server', 'sendMail', (subject, to, body) => {
});
}
};
and your second plugin which was loaded after the first one!
exports.plugin = {
name: 'anotherPlugin',
version: '0.0.1',
register: async function (server, options) {
server.sendMail("Hello", "test#test.com", "Sup?");
}
};
The difference between them, the server.methods object add custom fields to server.methods object but with the server.decorate you can directly extend your server or request objects. Use which one is more clear to you, I prefer server.decorate generally.

how to create individual i18next instances for different users on node server?

I am new to node.js. I am using i18next for internationalization in my node application. here is the code
utils.js
i18n.use(Backend).init({
debug: true,
load: ['ar','en'],
fallbackLng: 'en',
backend: {
loadPath: path.join(__dirname,'/{{lng}}/{{ns}}.json')
},
getAsync:false
}, (err, t) => {
return t;
});
exports.i18n=i18n;
For every request I am checking user language via cookies and if not matching I am trying to force the translations to that particular language.
Below is the snippet
app.all('*',function(req,res,next){
var lng = utils.getLanguage;
lng(req,res,function(data){
var i18n = utils.i18n;
i18n(function(i18n){
var nodeLanguage = i18n.options.lng||i18n.options.fallbackLng;
if(nodeLanguage == data){
next();
}
else{
console.log("not same");
i18n.options.lng = data;
i18n.init(i18n.options,function(){
next();
});
}
});
});
});
This code is working fine for me as i am single user.But If hit the same url in different browsers, it is showing in user selected language but i18next is initializing to latest user selected language. For example:-
case1 : In browser-1, selected en,then i18next.init method set the language to en.
case2 : In browser-2, selected fr, then i18next.init method is setting to fr.
If I hit the same URL in browser-1, again it is calling i18next.init method.
How to create individual i18next instances to individual users so as to avoid calling init method keep on ? Please help me.
Thanks.
use the middleware for express: https://github.com/i18next/i18next-express-middleware all you need is there, incl. language detection.

Dust.js load template from filesystem in Node.js

I'm trying to load template from file system using node.js and can't find the way.
So far I have:
exports.index = function(req, res){
var compiled = dust.compile("Hello {name}!", "intro");
dust.loadSource(compiled);
dust.render("intro", {name: "Fred"}, function(err, out) {
res.write(out);
res.close();
});
};
Is there is a way to replace: "Hello {name}!" with file name? Should it be HTML or JS file?
Also if that's not really great way on rendering templates let me know, I'm new to Node.js trying to pick up best practices.
fs.readFile(dustFile, function (err, file) {
var name = fileName.split(".")[0]
var fn = dust.compileFn(file.toString(), name)
fn({ name: "fred" }, function (err, out) {
res.end(out)
})
})
This should help you. dust fs.
This is a simplified interface to use templates from filesystem with {dust} using Node.js.
https://github.com/jheusala/dustfs

How to track usage on a node.js RESTful service with Google Analytics?

I've written a RESTful node.js service as a backend for http://www.cross-copy.net and would like to not only track usage of the web-client but also other clients (like commandline or Apps) which use the service for inter-device copy/paste. Is it possible to embed the Google Analytics JavaScript API into a node.js application and do server-side tracking?
Since all of the answers are really old, I will mention a new npm package:
https://www.npmjs.com/package/universal-analytics
It's really great and incredible easy to use.
Install universal analytics
npm install universal-analytics --save
In your routes file, require the module. (Replace process.env.GA_ACCOUNT with string like 'UA-12345678-1')
// Init GA client
var ua = require('universal-analytics');
var visitor = ua(process.env.GA_ACCOUNT);
Now inside your endpoint functions, you can track a pageview. (Replace request.url with the current url string like '/api/users/1')
// Track pageview
visitor.pageview(request.url).send();
Read the documentation on UA for more info on this module.
As Brad rightfully sad, there was nothing for Node... So I wrote a nodejs module tailored for this these last few days and just published it on NPM: node-ga
The module is still really new (barely trying it in production on a pet project), so don't hesitate to give your input :)
You won't be able to just drop ga.js into your Node project. It has to be loaded in a browser to function correctly.
I don't believe there is anything out there for Node yet (correct me if I'm wrong!), but you should be able to easily adapt the existing PHP classes for doing logging server-side:
https://developers.google.com/analytics/devguides/collection/other/mobileWebsites
You can see how the URL to request the tracking GIF is constructed within ga.php. Translate ga.php to JS and you're set.
$utmGifLocation = "http://www.google-analytics.com/__utm.gif";
// Construct the gif hit url.
$utmUrl = $utmGifLocation . "?" .
"utmwv=" . VERSION .
"&utmn=" . getRandomNumber() .
"&utmhn=" . urlencode($domainName) .
"&utmr=" . urlencode($documentReferer) .
"&utmp=" . urlencode($documentPath) .
"&utmac=" . $account .
"&utmcc=__utma%3D999.999.999.999.999.1%3B" .
"&utmvid=" . $visitorId .
"&utmip=" . getIP($_SERVER["REMOTE_ADDR"]);
I tried out node-ga, but didn't get event tracking to work. nodealytics did the job.
See Core Reporting API Client Libraries & Sample Code (v3).
There is also the following version: Google APIs Client Library for Node.js (alpha).
I wrote a script to query data with Node.js from Googles Analytics Core Reporting API (v3). The script and a detailed setup description is available here.
Here is the script part:
'use strict';
var googleapi = require('googleapis');
var ApiKeyFile = require('mywebsiteGAapi-6116b1dg49a1.json');
var viewID = 'ga:123456700';
var google = getdefaultObj(googleapi);
var Key = getdefaultObj(ApiKeyFile);
function getdefaultObj(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var jwtClient = new google.default.auth.JWT(Key.default.client_email, null, Key.default.private_key, ['https://www.googleapis.com/auth/analytics.readonly'], null);
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
var analytics = google.default.analytics('v3');
queryData(analytics);
});
function queryData(analytics) {
analytics.data.ga.get({
'auth': jwtClient,
'ids': viewID,
'metrics': 'ga:users,ga:pageviews',
'start-date': 'yesterday',
'end-date': 'today',
}, function (err, response) {
if (err) {
console.log(err);
return;
}
console.log(JSON.stringify(response, null, 4));
});
}

Resources