Sync a PouchDB on Nodejs server (without Pochdb-server or Couch) - node.js

I want to Sync() the PouchDb on my Nodejs-server with the IndexedDb at frontend.
But : I dont use Couch or Pouchdb-server
on Backend I'm runnig :
var pouch = require('pouchdb')
var db = new pouch('fuu');
test.app.use('/sync'),function(req,res,next){console.log('Woop woop');
db.info(function)(err,info) {return res.send('info')})
});
// same problem with : db.allDocs(..);
on frontend:
var db = new PouchDB('ba');
var remoteCouch = ("http://localhost:3000/sync")
var sync = function() {
var opts = {live: true};
db.sync(remoteCouch, opts);}
sync();
But now there is an endless call of 'Woob woob' in the console and nothing sync's ..
Have someone an idea what I'm doing wrong?

You need to correctly map all the urls that PouchDB will use to be able to sync. I aassume your backend is a typo and you are using var db = new PouchDB('fuu') on the backend right?
PouchDB-Server has extracted the url routing logic it uses into another module, https://github.com/pouchdb/express-pouchdb, the README should give you an example of how to do that and you dont need the extra functionality provided by pouchdb-server

Related

How can I verify I don't need the mLab add-on for my Heroku node.js app?

After reading through the mLab -> Atlas migration plan a few times, I decided I'd try a different way. My coding background is mainly asm on mcs51 so I'm something of a n00b in the node.js/mongo/heroku world. I barely understood half of the migration process.
So I wrote a small test app following this blog entry and then used what I'd learned to modify my actual app to talk to Atlas directly. I exported the collections from the old db to JSON, then imported them into the Atlas version to recreate the database. Everything appears to be working correctly; I don't see any data going into the old db and it looks like the new Atlas db is getting all the action.
But I'm leery of deleting the mLab add-on from Heroku until I've verified that it's truly not needed any more, because I'm pretty sure that I won't be able to recreate it if it turns out I've missed something.
So my question is, how can I ensure I'm no longer using the mLab add-on? I don't really understand what it was doing for me in the first place so I'm not sure how to verify I'm not using it any more.
Here are the relevant code snippets I'm using to access the Atlas db...
function myEncode(str) { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
const ATLASURI = process.env.ATLASURI;
const ATLASDB = process.env.ATLASDB;
const ATLASUSER = process.env.ATLASUSER;
const ATLASPW = myEncode(process.env.ATLASPW); // wrapper needed to handle strong paswords...
const dbURL = "mongodb+srv://"+ATLASUSER+":"+ATLASPW+"#"+ATLASURI+"/"+ATLASDB+"?retryWrites=true&w=majority";
var GoogleStrategy = require('passport-google-oauth20').Strategy;
const {MongoClient} = require('mongodb');
const client = new MongoClient(dbURL, { useNewUrlParser: true, useUnifiedTopology: true });
var store = new MongoDBStore({uri: dbURL,collection: 'Sessions'});
var db = undefined;
client.connect(async function(err) {
if(err) {console.log("Error:\n"+String(err));}
db = await client.db(ATLASDB);
console.log("Connected to db!");
banner();
});

How can I read the mp3 files from the mongodb that I have stored using gridFS?

My code:
storeAudio.js
var mongoose = require('mongoose');
var fs = require('fs');
var Grid = require('gridfs-stream');
Grid.mongo=mongoose.mongo;
//establish mongoDB connection
mongoose.Promise = global.Promise;
var conn = mongoose.createConnection('mongodb://localhost:27017/aHolyBoly');
conn.once('open',function(){
var gfs = Grid(conn.db);
// var db = new mongo.Db('aHolyBoly', new mongo.Server("127.0.0.1", 27017));
//var gfs = Grid(db, mongo);
var writeStream = gfs.createWriteStream({
filename:'song1.mp3'
});
fs.createReadStream('../list/hero.mp3').pipe(writeStream);
writeStream.on('close',function(file){
console.log(file.filename +'Written to db');
});
});
my mp3 file is written successfully in the DB.
Now my aim is to create the routes using express so that I can use it as an API using as providers in my angular2 app.
server.js
var mongoose = require('mongoose');
var fs = require('fs');
var Grid = require('gridfs-stream');
Grid.mongo=mongoose.mongo;
//establish mongoDB connection
mongoose.Promise = global.Promise;
var conn = mongoose.createConnection('mongodb://localhost:27017/aHolyBoly');
conn.once('open',function(){
var gfs = Grid(conn.db);
// var db = new mongo.Db('aHolyBoly', new mongo.Server("127.0.0.1", 27017));
//var gfs = Grid(db, mongo);
var writeStream = gfs.createWriteStream({
filename:'song1.mp3'
});
fs.createReadStream('../list/hero.mp3').pipe(writeStream);
writeStream.on('close',function(file){
console.log(file.filename +'Written to db');
});
});
Here somewhere in my code, I am unable to find the song written in the Db using gridFS.
link for gridFS API gridFS API Link
I want to create an application using ionic2 which contains a search bar and when I enter song name it will display the songs and I can play it.
I am struggling from 1 week written this 3 times on stack but unable to get the answer.
I bet you are a newbie in server-side web development, because your question kinda misses the whole point of creating a node.js application.
When writing a server the goal is that the server cannot access the files on the client's computer. This means your app acts as a thin client. Don't confuse that node.js runs on your computer as well: it creates his own mock server which acts as a real faraway computer even though it is on your very same computer that you use. For this reason you cannot modify files outside of your project library, or even if you can it will be a hack and it is not what node.js is made for.
If you want a program specifically to modify files on your computer you should learn a thick client programming language, like C, C++ or Java. They only run on your computer ad have full access to any of your files.
If you are sticking to JavaScript for whatever reason, it as well has the power to modify your files, however it is still not what it is intended for. You have to give it special permissions and it still is weird that you give access to all your personal files to your browser. However this Javascript code id on the client side i.e. you don't need node.js, neither express. The client code can be written and run with a single browser. Check out this article for more information about it.
But if you are still convinced that node is your way, then you have some options still. First, but I don't think it is your answer: write an upload website which uploads the mp3 files to your server (still on the same computer but places it in the project location). It should work and look like an actual website (like what node.js was made for). And finally what you're asking for can be kinda achieved, but it's reaaaaally hacky, you can try and just reference it from the application path like
var fs = require('fs'),
path = require('path'),
filePath = path.join(__dirname, '../outerfile.mp3')
filePath2 = path.join('/var/outerfile.mp3');
However it is probably platform dependent how it will run and not likely to be working at all.
My final advice: you should consider using another language for your project.

mongodb not erroring with wrong uri

I am having big problems trying to wrap my head around mongodb.
First of all, I tried using mongoose, but I really don't like its schemas, I want to have my own classes, and perform CRUD operations in a classic style.
So I moved on and started using mongodb. I think I already gonna give up and use MySQL, because I find their documentation very very obscure, and also no public issue tracker on github.
Anyway, my problem is that if I connect to a non existing db or to a non existing host, mongodb isn't showing any error.
My code:
const mongodb = require( 'mongodb' ),
MongoClient = mongodb.MongoClient;
let db_uri = `mongodb://${config.host}:${config.port}/${config.name}`;
MongoClient.connect( db_uri, function( err, mongoclient ) {
console.log( err );
});
Assume that config.host or config.port are not correct.
err is alway null.
Why is this ?
Mongodb does this great(and in some cases really annoying thing if you have fat fingers) where if you attempt to connect a database that doesn't exist, it will create it for you. I knew it did this in command line, but it appears it does it with this code as well. Using the insert code from the npm node instructions I was able to test and verify this.
Edit- removing example and adding something actually helpful
It may be cumbersome, but there is a way to test if a collection exists. You ask if an index exists.
const mongodb = require( 'mongodb' ),
MongoClient = mongodb.MongoClient;
var db_uri = "mongodb://localhost:27017/newDb";
MongoClient.connect( db_uri, function( err, db ) {
var collection = db.collection('documents');
collection.indexExists(0, function(err, indexExists){
});
});

NodeJS (Express) - project structure and mongo connection

I started a new project from scratch with ExpressJS.
Everything works fine but now I begin to have a dozen of 'app.get(....)' function and I need to give the project a structure.
What I have in mind is quite simple, it should have a folder named 'routes' containing a file such as 'module1.js', with all of the app.get related to that module. (like I've seen in many examples)
The issue is how to tell Express to route 'http://url/module1/' to that route file and how to pass it a param variable, containing for instance the mongodb connection.
what I tried is :
var params = {
db: myMongoConnection
};
var mod1 = require('routes/module1');
app.use('/module1', mod1);
but now I still miss the 'params'.
If I try to pass it as an argument to the require method i get an error saying it needs middleware.
Another issue is related to the fact that the myMongoConnection is valid in the connection callback, so I think i need to require and use the route.js inside the MongoClient connect callback.
Any idea?
thanks a lot
For custom modules, create a folder, call it modules
In its index.js, expose the modules that you need.
Something like,
var mods = [
'mod1',
'mod2',
];
function init() {
var expose = {};
var params = {
db: myMongoConnection
};
mods.forEach(mods, function (mod) {
expose[mod] = require('./' + mod)(params);
});
return expose;
}
// export init
module.exports = init;
In mod1.js, wrap the params
module.exports = function(params) {
// all your functions here will have access to params.
}
Then in, server/app.js, require this and set it in the app.
app.set('mods', require('path-to/modules'));
Now, you can access all your modules, using app.get('mods').moduleName.methodname

Where do I put database connection information in a Node.js app?

Node.js is my first backend language and I am at the point where I am asking myself "where do I put the database connection information?".
There is a lot of good information regarding this issue. Unfortunately for me all the examples are in PHP. I get the ideas but I am not confident enough to replicate it in Node.js.
In PHP you would put the information in a config file outside the web root, and include it when you need database data.
How would you do this in Node.js? using the Express.js framework.
So far I have this:
var express = require('express'), app = express();
var mysql = require('mysql');
app.get('/', function(req,res) {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'store'
});
var query = connection.query('SELECT * from customers where email = "deelo42#gmail.com"');
query.on('error', function(err) {
throw err;
});
query.on('fields', function(fields) {
console.log('this is fields');
});
query.on('result', function(row) {
var first = row.first_name;
var last = row.last_name;
res.render('index.jade', {
title: "My first name is " + first,
category: "My last name is " + last
});
});
});
app.listen(80, function() {
console.log('we are logged in');
});
As you can see I have a basic express application with 1 GET route. This route sets off the function to go to the database and pull out information based on an email address.
At the top of the GET route is the database connection information. Where do I put that? How do I call it? How do I keep it out of web root, and include it like PHP ? Can you please show me in a working example. Thanks!
I use the Express Middleware concept for same and that gives me nice flexibility to manage files.
I am writing a detailed answer, which includes how i am use the config params in app.js to connect to DB.
So my app structure looks something this:
How i connect to DB? (I am using MongoDB, mongoose is ORM, npm install mongoose)
var config = require('./config/config');
var mongoose = require("mongoose");
var connect = function(){
var options = {
server: {
socketOptions:{
keepAlive : 1
}
}
};
mongoose.connect(config.db,options);
};
connect();
under the config folder i also have 'env' folder, which stores the environment related configurations in separate files such as development.js, test.js, production.js
Now as the name suggests, development.js stores the configuration params related to my development environment and same applies to the case of test and production. Now if you wish you can have some more configuration setting such as 'staging' etc.
project-name/config/config.js
var path = require("path");
var extend = require("util")._extend;
var development = require("./env/development");
var test = require("./env/test");
var production = require("./env/production");
var defaults = {
root: path.normalize(__dirname + '/..')
};
module.exports = {
development: extend(development,defaults),
test: extend(test,defaults),
production: extend(production,defaults)
}[process.env.NODE_ENV || "development"]
project-name/config/env/test.js
module.exports = {
db: 'mongodb://localhost/mongoExpress_test'
};
Now you can make it even more descriptive by breaking the URL's into, username, password, port, database, hostname.
For For more details have a look at my repo, where you can find this implementation, in fact now in all of my projects i use the same configuration.
If you are more interested then have a look at Mean.js and Mean.io, they have some better ways to manage all such things. If you are beginner i would recommend to keep it simple and get things going, once you are comfortable, you can perform magic on your own. Cheers
I recommend the 12-factor app style http://12factor.net which keeps all of this in env vars. You never should have this kind of information hard-coded or in the app source-code / repo, so you can reuse it in different environments or even share it publicly without breaking security.
However, since there are lots of environment vars, I tend to keep them together in a single env.js like the previous responder wrote - although it is not in the source code repo - and then source it with https://www.npmjs.org/package/dotenv
An alternative is to do it manually and keep it in, e.g. ./env/dev.json and just require() the file.
Any of these works, the important point is to keep all configuration information separate from code.
I agree with the commenter, put it in a config file. There is no ultimate way, but nconf is also one of my favourites.
The important best practise is that you keep the config separate if you have a semi-public project, so your config file will not overwrite other developers.
config-sample.json (has to be renamed and is tracked with for example git)
config.json (not tracked / ignored by git)

Resources