MongoJS, Node, MongoLab - How to get the database online - mongodb

I have created an hybrid application with Ionic, MongoJS, Angular JS (Mean Stack).
My application worked fine, locally. This means my mongod (Mongo Service) and my mongo ran locally on my pc. I also have a server.js (node) which is located locally.
Now I would like to use MongoLab (MongoDB as a Service) to change the location of my database from local to online.
I intented to change just the connection path, but for some reason I receive an undefined through my http get request.
My code:
server.js
var express = require('express');
var app = express();
var mongojs = require('mongojs');
//var db = mongojs('nzbaienfurtdb', ['nzbaienfurtdb']); // This is my old mongojs which ran locally and worked fine.
var databaseUrl = 'mongodb://dbuser:password#ds045604.mongolab.com:45604/nzbaienfurtdb';
var db = mongojs(databaseUrl, ['nzbaienfurtdb']); // database online with MongoLab
var bodyParser = require('body-parser');
app.use(express.static(__dirname + "/www"));
app.use(bodyParser.json());
app.get('/nzbaienfurtdb', function (req, res) {
console.log("I received a GET request")
db.nzbaienfurtdb.find(function (err, docs){
console.log(docs);
res.json(docs);
});
});
app.listen(3000);
console.log("server running on 3000");
This is a part of my get request out of a service:
service.js
return {
getUsers: function(){""
$http.get("/nzbaienfurtdb")
.success(function(data, status, headers, config){
headers("Cache-Control", "no-cache, no-store, must-revalidate");
headers("Pragma", "no-cache");
headers("Expires", 0);
users = angular.fromJson(data);
})
.error(function(data, status, headers, config){
console.log('Data could not be loaded, try again later');
})
return users;
}
MongoLab has been setup already.
My questions:
Why do I get an undefined for my http GET Request?
What happens with my server.js file when I want to deploy the Ionic App on for example an Android Phone? Is the server running on the device?
Since I have changed the var db variable i get also the following error message in my chrome console:
--------- ERROR CODE:
SyntaxError: Unexpected end of input
at Object.parse (native)
at Object.fromJson (http://localhost:3000/lib/ionic/js/ionic.bundle.js:8764:14)
at http://localhost:3000/js/userServices.js:23:27
at http://localhost:3000/lib/ionic/js/ionic.bundle.js:15737:11
at wrappedCallback (http://localhost:3000/lib/ionic/js/ionic.bundle.js:19197:81)
at wrappedCallback (http://localhost:3000/lib/ionic/js/ionic.bundle.js:19197:81)
at http://localhost:3000/lib/ionic/js/ionic.bundle.js:19283:26
at Scope.$eval (http://localhost:3000/lib/ionic/js/ionic.bundle.js:20326:28)
at Scope.$digest (http://localhost:3000/lib/ionic/js/ionic.bundle.js:20138:31)
at Scope.$apply (http://localhost:3000/lib/ionic/js/ionic.bundle.js:20430:24)
I hope somebody can help me out, I am fighting now for ages!
Thank you in advance, guys!

This issue has been resolved after ages!
I had to enable the API on the website of mongolab in my configuration.

Related

flutter web: how to connect to a rest API or localhost

My code:
void checkState() async {
print("CTC");
var url = "http://localhost:3000";
try {
var respX = await http.get(url);
} catch (err) {
print("response Arrived: $err");
}
}
But it is not possible:
https://github.com/flutter/flutter/issues/43015#issuecomment-543835637
I am using google chrome for debugging. simply pasting http://localhost:3000 allows me to connect to the URL from the same browser.
Is there any way to do it?
This issue was not with the flutter. It is the CORS policies in the browser as well as the server that blocked the request. I hosted it in a nodejs server with express. Here what I have did to solve this:
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
You can change the 'Access-Control-Allow-Origin' to the domain you are calling from if you want to. Else it will allow request from everywhere.
Remember, the localhost of your emulator is not the localhost of your machine. To test the API running on your machine you have to point to the ip adress of your computer

Parse Server - Image files' path returns localhost

I have deployed 2 Ubuntu servers on Azure. First, I have installed the Parse Server and the second, I installed MongoDB. (I have also put a ready db there from my previous server via mongorestore)
Everything works fine! Both Parse Server and MongoDB server. They also communicate well. The thing is, when I run my iOS app, it brings all data correctly, except images. I print the URL of an image and here's what it returned: http://localhost:1337/parse/files/filename.jpeg
If I replace localhost with my server's ip, the image is being fetched nicely!
Here's what I have on my index.js:
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var ParseDashboard = require('parse-dashboard');
var allowInsecureHTTP = true;
var path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri || 'mongodb://IP:27017/db',
cloud: './cloud/main.js',
appId: process.env.APP_ID || 'xxx',
masterKey: process.env.MASTER_KEY || 'xxx', //Add your master key here. Keep it secret!
fileKey: 'xxx',
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't forget to change to https if needed
// Enable email verification
verifyUserEmails: false,
// The public URL of your app.
// This will appear in the link that is used to verify email addresses and reset passwords.
// Set the mount path as it is in serverURL
publicServerURL: 'http://localhost:1337/parse',
});
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
// If you wish you require them, you can set them as options in the initialization above:
// javascriptKey, restAPIKey, dotNetKey, clientKey
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('Make sure to star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// Set up parse dashboard
var config = {
"allowInsecureHTTP": true,
"apps": [
{
"serverURL": "http://localhost:1337/parse",
"appId": "xxx",
"masterKey": "xxx",
"appName": "name",
"production": true
}
],
"users": [
{
"user":"username",
"pass":"pass"
}
]
};
var dashboard = new ParseDashboard(config, config.allowInsecureHTTP);
var dashApp = express();
// make the Parse Dashboard available at /dashboard
dashApp.use('/dashboard', dashboard);
// Parse Server plays nicely with the rest of your web routes
dashApp.get('/', function(req, res) {
res.status(200).send('Parse Dashboard App');
});
var httpServerDash = require('http').createServer(dashApp);
httpServerDash.listen(4040, function() {
console.log('dashboard-server running on port 4040.');
});
One thing I noticed at Parse's documentation, is this: When using files on Parse, you will need to use the publicServerURL option in your Parse Server config. This is the URL that files will be accessed from, so it should be a URL that resolves to your Parse Server. Make sure to include your mount point in this URL.
The thing is that this documentation was written having in mind MongoDB, is on the same server with Parse, which in my case isn't.
Any ideas on what to do?
I had to replace the publicServerURL of parse server's config, from http://localhost:1337/parse to http://publicIP:1337/parse and everything worked out great!
If you want to work with files(images) download them, just use publicServerURL as mentioned #Sotiris Kaniras
I would add that the config.json is in ~/stack/parse/config.json. Also here is the difference between serverURL and publicServerURL
Difference between serverURL and publicServerURL on ParseServer
In my case, I needed to add publicServerURL parameter alongside with serverURL because it hasn't existed yet.
So both parameters(publicServerURL & serverURL) are complement, not mutually exclusive, use them both.

cannot GET / express.js routing

I am at the early stages of a simple tasks manager that I want to build with the MEAN Stack.
I can figure/resolve a simple routing issue. I don't see any error message in the terminal or console except for the 404 client error.
the root path is ok. I get a response back
I use html docs to render the ui for both.
this is how I have set up my server.js
var express = require('express')
var path = require('path')
var bodyParser = require('body-parser')
var index = require('./routes/index');
var tasks = require('./routes/tasks');
var app = express();
const port = '3456'
app.use('/', index)
app.use('api', tasks) <= HERE
//view engine
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')
app.engine('html', require('ejs').renderFile);
//static folder
app.use(express.static(path.join(__dirname, 'client')))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
app.listen(port, function() {
console.log('Starting the server at port' + port );
})
tasks.js
to render the template at the set route
var express = require('express')
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('mongodb://sandy:cookie2080#ds147304.mlab.com:47304/tasklists_21092017', ['tasks'])
router.get('/tasks', function(req, res, next) {
res.send('api')
res.render('tasks.html')
db.tasks.find(function(err, tasks){
if (err) {
res.send('error message ' + err)
}
res.json(tasks)
})
})
module.exports = router;
and, index.js fyi
var express = require('express')
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index.html')
})
module.exports = router;
screenshot at the link below of the 404 error in browser after starting server on port 3456
404 error - screenshot
thanks for the help. I am sure it can be a little detail. it is very hard to debug though.
This error occurs because there's no route that handles the endpoint /api. What you can do here is create a middleware that will handle the /api. You can do it in your tasks.js like this:
tasks.js
router.get('/', function(req, res, next) {
res.send('This is api.')
})
Or if what you want to do is to direct the user from the endpoint /api to /api/tasks then you could do it like this:
router.get('/', function(req, res, next) {
res.redirect('/api/tasks')
})
Hope this helps.
I changed the port number. The issue was that the port 3000, was not responding to the requests, as it was still in use by an older process hence producing the warning
errno: 'EADDRINUSE',.
Just used the port 5000 to try out and it went through smoothly.
By the way I am using vs code.

socket.io: Failed to load resource

I'm trying to getting started with socket.io and node.js.
Following the first example on the socket.io's site I'm getting the following error in the browser's console:
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3001/socket.io/socket.io.js
Uncaught ReferenceError: io is not defined
This is my server.js
var app = require('express').createServer()
, io = require('socket.io').listen(app);
app.listen(3001);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
And this is my index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8" />
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</body>
</html>
I've already installed socket.io..
The Issues
First of all you need to be looking at the server port that the server is bound on (app.listen(3001);) on the client side in order to reach the server at all.
As for socket.io, adding http://localhost:3001 before the rest of the source in the link tag solves this problem. This is apparently due to the way the network binds ports to localhost, however I will try to find some more information on the cause;
What to change:
The port binding for the server:
var socket = io.connect('http://localhost');
should be change to
var socket = io.connect('http://localhost:3001');
Making socket.io behave:
<script src="/socket.io/socket.io.js"></script>
should be change to
<script src="http://localhost:3001/socket.io/socket.io.js"></script>
If you are using express version 3.x there are Socket.IO compatibility issues that require a bit of fine tuning to migrate:
Socket.IO's .listen() method takes an http.Server instance as an argument.
As of 3.x, the return value of express() is not an http.Server instance. To get Socket.IO working with Express 3.x, make sure you manually create and pass your http.Server instance to Socket.IO's .listen() method.
Here is a quick example:
var app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
server.listen(3000);
Firstly, the Socket.io "How To Use" documentation is vague (perhaps misleading); especially when documenting code for the Socket.io client.
Secondly the answers you've been given here on StackOverflow are too specific. You shouldn't have to manually hardcode the protocol, hostname, and port number for the Socket.io client; that's not a scalable solution. Javascript can handle this for you with the location object - window.location.origin.
Getting started with Socket.io
Installation
Socket.io requires the installation of a server and client.
To install the server
npm install socket.io
To use the client, add this script to your document (index.html)
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
Implementation with Express 3/4
Create the following files:
Server (app.js)
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client (index.html)
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
// origin = http(s)://(hostname):(port)
// The Socket.io client needs an origin
// with an http(s) protocol for the initial handshake.
// Web sockets don't run over the http(s) protocol,
// so you don't need to provide URL pathnames.
var origin = window.location.origin;
var socket = io.connect(origin);
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
change;
<script src="/socket.io/socket.io.js"></script>
to;
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js" integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k" crossorigin="anonymous"></script>
and drop between to head tags.
And Try it!
If you're trying to make this run on a different computer and you are getting this error, you may find this useful.
var host = window.location.hostname;
var socket = io.connect('http://' + host);
If you're using https, then obviously you need to change the protocol as well. In my case I needed to create a server that would run on several local computers, so putting here a fixed address would not work, as the socket would need to connect to a different address depending on what server you are loading the page from. Adding this here as it may help someone else too.
Try this
var app = express()
,http = require('http');
var server = http.createServer(app);
server.listen(3001);
io = require('socket.io').listen(server);
io.set('log level', 1);
Hope it helps
The following changes finally worked for me
const app = express(); const http = require('http'); const server = http.createServer(app); const io = require('socket.io')(server)
I know this is very very late, but I found a solution for those who might have previously set node.js up. My machine needed get hardware replaced, when it came back, I noticed quite a few settings were back to factory default. I was also getting the error discussed above.
Running
sudo apachectl start
from the terminal fixed up my issue.

Node.js connect-mongo database connection problem

This is a very weird problem with "connect-mongo"
In my server, I have two scripts.
1) create the express server with session with Mongo DataStore: It has no problem for connection or creating the session.
MongoStore = require('connect-mongo'),
app = require('express').createServer(
express.session({ secret: cfg.wiki_session_secret,
store:new MongoStore({
db: 'mydatabase',
host: '10.10.10.10',
port: 27017
})
})
);
2) just create the store without express:
var MongoStore = require('connect-mongo');
var options = {db: 'mydatabase'};
var store = new MongoStore(options, function() {
var db = new mongo.Db(options.db, new mongo.Server('10.10.10.10', 27017, {}));
db.open(function(err) {
db.collection('sessions', function(err, collection) {
callback(store, db, collection);
});
});
});
That will throw the connection problem:
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Error connecting to database
at /home/eauser/node_modules/connect-mongo/lib/connect-mongo.js:106:13
at /home/eauser/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:79:30
at [object Object].<anonymous> (/home/eauser/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/connections/server.js:113:12)
at [object Object].emit (events.js:64:17)
at Array.<anonymous> (/home/eauser/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/connection.js:166:14)
at EventEmitter._tickCallback (node.js:126:26)
I just don't know why..
connect-mongo is a middleware for the connect framework, which express is based on.
So, you must use the middleware with the express framework or the connect framework, otherwise it won't work. It's not written to be a standalone session library.
You can go for mongoose to connect. Install using npm command
npm install mongoose
Install mongoose globally
npm install -g mongoose
app.js
var mongoose = require("mongoose");
This module has callback in the constructor which is called when the database is connected, and the collection is initialized so it won't work as you expect.
I've the same problem than you and I wanted the same interface that you aim here. So I wrote another module called YAMS - Yet Another Mongo Store. This is an example with YAMS:
var MongoClient = require("mongodb").MongoClient;
var Yams = require('yams');
var store = new Yams(function (done) {
//this will be called once, you must return the collection sessions.
MongoClient.connect('mongo://localhost/myapp', function (err, db) {
if (err) return done(err);
var sessionsCollection = db.collection('sessions')
//use TTL in mongodb, the document will be automatically expired when the session ends.
sessionsCollection.ensureIndex({expires:1}, {expireAfterSeconds: 0}, function(){});
done(null, sessionsCollection);
});
});
app.usage(express.session({
secret: 'black whisky boycott tango 2013',
store: store
}));
This is in my opinion more flexible than the connect-mongo middleware.