AngularJS - Interaction with mongodb - javascript

I am new to MEAN stack, I am trying to create a basic one page application at the moment.
I am trying to connect to the mongodb and then list the values in a certain collection in a controller.
However, when I looked for the answer, I came across this answer
Using AngularJs and MongoDB/Mongoose
Which then confuses me as what is the point of having the code below if you can't use it between angular and mongo ? Or are there other interim steps that use it?
var mongoose = require('mongoose');
var db = mongoose.createConnection('mongodb://localhost:3000/database');
var orderSchema = new mongoose.Schema({
routeFrom : String,
routeTo : String,
leaving: String
});
var Order = db.model('Order', orderSchema);
module.exports = Order;
Edit: The situation i am trying to use it in is such:
Geek.html
<div class="jumbotron text-center">
<h1>Geek City</h1>
<p>{{tagline}}</p>
<ul>
<li ng-repeat="value in dataValues">
{{value.name}}
</li>
</ul>
</div>
GeekController
angular.module('GeekCtrl', []).controller('GeekController', function($scope) {
$scope.tagline = 'The square root of life is pi!';
$scope.dataValues = function(){
var mongo = require('../config/db.js');
var collectionValues = mongo.myCollection.find();
return collectionValues;
};
});

You cannot require db.js config file in Angular because it's not set to be used on the client side. What you describe is so called 'Isomorphic' approach.
What I mean by that: mongo is a database system (roughly speaking). To get data from the database, we usually don't trust the client. So we have some server-side code (PHP, Ruby, Node.js, Java, what have you) which authorizes the client, processes and filters the data and returns it to the client (in this case Angular.js). So your Mongoose models are set to be used by the server-side javascript and that part of the app. That server side should also serve data to Angular so you'd connect to Node.js from Angular, not directly to Mongo. So the same server that (usually) serves your angular files, will also serve the data it reads from mongo.
If you want server-less data with Angular, you can take a look at Firebase.js. It's angular-ready and it could help you not mess around with Mongo, mongoose and the server-side code.
You could try a hybrid approach with something like meteor.js or backbone.js set to work both on client and server, or take a look at this article for more info.
Or for what it's worth, if you want to run your own Mongo, you could start mongo with --rest, then you'd be able to connect to Angular directly to Mongo, at http://somehost:28017/mydatabase or something similar, depending on your setup.

Mongoose is a node module, and as far as I know it doesn't have a front end component, so you won't be using it directly in your frontend js code. It's only going to help you on the server side of your app. If you're relatively new to Node then this stuff can get pretty confusing, since it's all end-to-end javascript and sometimes it's not clear what modules work on the server or frontend, especially since some can do both.
Node, MongoDB, Express, and Mongoose all live on the server.
Angular lives in the browser, and can't use any of the server-side components directly.
Using the MEAN stack, You will be building a node app that uses mongoose to talk to mongodb and express to expose an api to your front end. Then in in your html/js code you'll be using angular and its $http service to talk to the server to get and set data.
There is a great tutorial that walks you through the entire process on scotch.io:
http://scotch.io/bar-talk/setting-up-a-mean-stack-single-page-application

Related

How can I reference data from MariaDB on web browser JS application?

I am trying to create a webpage that uses data from a MariaDB. My current idea (which has been giving me a lot of trouble) is to just connect to the database from the app.js file, which is the main script for my index.html.
const dotenv = require("dotenv");
dotenv.config();
const mariadb = require("mariadb");
const pool = mariadb.createPool({
database: process.env.DATABASE,
host: process.env.HOST,
user: process.env.USER_TOKEN,
password: process.env.PASSWORD,
});
// the rest of the code involves selecting from the db, and parsing the data
However, I have been running into many issues. I'm not too knowledgeable on all this, but I found that I need to webpack the file if I want to be able to use the "require" keyword. But I could not figure that out as I kept running into weird issues when using Browserify; I think there may be an incompatibility with MariaDB. I also looked into using JS modules, but I am not sure if that is possible with MariaDB.
I am trying to come up with another solution, potentially using some sort of API to a back end, which would make the GET request to the database, but I feel like it should not have to be that complicated for my sake (I also wouldn't really know where to start with this). All I basically want to do, is make a GET request to a MariaDB when the page loads on the client's browser and display that data on the webpage. Is there a simple way to do this?
I suggest you use nodejs to connect and query database as it will greatly resolve a lot of overhead for you..
The easiest way i can think of is using a prisma starter template here
https://github.com/prisma/prisma-examples/tree/latest/javascript/script
It also gives the added advantage of the ORM function...
Hope it helps.

Node Backend Application Database Connection Objectorientated

I am working on a backend application with node using typescript / javascript. My backend is using a sqlite database. I structured my project so that there is one file that contains all the database logic.
I could either write a module that will be required by all modules that or I could write a class which connects to the database in the constructor.
For me it seems a little bit weird to pack all database logic in a module that is not an object. What is the best practice in this case and why? (I know this might be a stupid question but I'm just a hobbyist)
Thanks in advance
In my case I make the connection to the database before running the server. In pseudocode:
connectorDB.connect( path, config, () => {
server.listen( port )
})
It will depend on how important the database connection is in the operation of your app.

Keeping a client-side sync of Sails.js collection, using sockets

I very much like Meteor's pub/sub. I wonder if there is a way to get a similar workflow, using sails.js or just a socket library in general.
In particular, what I would like to be able to do is something along the lines of:
// Server-side:
App.publish('myCollection', -> collection.find({}))
// Client-side:
let myCollection = App.subscribe('myCollection')
let bob = myCollection.find({name: 'Bob'})
myCollection.insert({name: 'Amelie'}, callback)
All interaction with the server should happen in the background.
I very much like Meteor's pub/sub. I wonder if there is a way to get a similar workflow, using sails.js or just a socket library in general
Basically yes, at least about realtime sync between backend and frontend. Let's review what meteor's have and answer point by point.
Pub/sub
The Pub / Sub concept, as stated by Sabbir, is also supported by sails.js. Though the basics are slightly different :
In meteor, the client can subscribes to everything he wants, and the server control what it receives by only publishing to who he wants;
whereas in sails.js, the server both does subscribe some clients sockets and publish to all binded sockets
Note that, by default:
meteor contains the autopublish package that just notify every client without any kind of filtering. To acheive some filtering, you have to meteor remove autopublish then you can handle what will your client receive by adding a mongo request to it, like explained here.
sails by default, on its automatic "select" blueprints actions, auto-subscribes the calling socket to the events on the objects returned by the "select".
As a server-side conclusion:
Subscribe: just call findor findOne blueprint default action, through a socket (attaching some where filters or not) and your socket will automatically be subscribed to every events concerning returned objects => you don't have to code anything on the server, in most cases, for the Subscribe logic.
Publish: every blueprint default actions (create, update, destroy, add, remove) auto-publish to subscribed sockets => you don't have to code anything on the server, in most cases, for the Publish logic.
(Though, if you find yourself implementing some manual controller actions, sails API helps you publishing and subscribing easily)
Client handling
Therefore, with both meteor and sails, clients only receive what they're supposed to receive. Time for front-end now.
Philosophy
meteor in one hand, with it's isomorphic dimension, does provide a front-end connector by nature, exposing it's data-bound collections.
sails on the other hand, is front-end agnostic, and can be attacked by any http REST connector (JS or not), such as $http, $resource, or more advanced ones like Restangular.
Though, being aware of the complexity using raw sockets on their API (when it comes to session, CORS, CSRF and stuff), they developped a javascript socket.io wrapper called sails.io.js designed to be REST-like-over-socket, and just works like a charm.
Basically, The main difference is that meteor is one step higher-level than sails, because it provides the logic of syncing collections and objects.
All interaction with the server should happen in the background.
sails.io.js, the official front-end component, is just not that high-level. When it comes to Angular.js.
Though, you can find some community connectors that aim to, kinda, provide the same feature as mongo data-bound collections and objects. There is sails-resource, spinnaker or angular resource sails. I tried both of them, and I should say that I was disapointed. The abstraction level is so high that it just becomes annoying, IMHO. For example, with not-very-RESTful-friendly custom actions, like a login, it becomes very hard to adapt it for your needs.
==> I would advice to use a low-level connector, such as angularSails or (my prefered) https://github.com/janpantel/angular-sails, or even raw sails.io.js if you're not using Angular.
Edit: just foun a backbone version, by the sails' creator
It just works great, and believe me, the "keep my collection in sync with that socket" code is so ridiculous, that finding a module for this is just not worth it.
Some code please, stop talking
In particular, what I would like to be able to do is something along the lines of:
Server
Meteor
# Server-side:
App.publish('myCollection', -> collection.find({}))
Sails
//Nothing to do, just sails generate api myCollection
Client
Meteor
# Client-side:
myCollection = App.subscribe('myCollection')
Sails, with sails.io.js
(Here using lodash for convenience)
var myCollection;
sails.io.get('/myCollection').then(
function(res) {
myCollection = res.data;
},
function(err) {
//Handle error
}
);
sails.io.on('myCollection').function(msg) {
switch(msg.verb) {
case 'created':
myCollection.push(msg.data);
break;
case 'updated':
_.extend(_.find(myCollection, 'id', msg.id), msg.data);
break;
case 'destroyed':
_.remove(myCollection, 'id', msg.id);
break;
};
});
(I leave the find where and create to your imagination with [the doc])
All interaction with the server should happen in the background.
Well, Sails, only for angular, with sails ressources
I'm not pretty used to that process, so I leave you reading here or here, but once again I'd choose manual .on()method.
Since I asked this question, I've learned a few things and some new projects have popped up. I decided against sails.io, because when developing with React.js, most of the community's weight is behind webpack, but sails.io uses gulp. I realize these can be used together and there is even an npm package for this, but I wasn't too keen on making my stack bigger than it had to be, so I went with a simple express.js server that I could tailor to my needs.
In order to sync my data, I'm using rethinkdb which allows me to asynchronously watch the database for changes and then publish the changes to the clients through websockets.
I've set up a simple script where I keep an instance of a baobab tree on both the client and the server.
When the tree gets modified on the server, it sends transaction data to the appropriate clients through the websocket
The client merges the transaction with the tree.
This method does not make use of local storage and keeps the data in memory in the node.js process. The data in the transaction is also quite redundant.
The future plan has always been to set something up using redis and local storage ...
... until yesterday when I found deepstream.io!
This is a tool that does exactly what I want and need! Nothing more, nothing less.
Another project worth mention is meatier: "like meteor, but meatier". It is composed of many other well supported open source projects, so you could even pick and choose.

Frontend accessing MongoDb

For a project, we're going to use the MEAN stack. Having Angularjs as the frontend framework, is there a possibility for the framework directly accessing the data from mongodb (Bypassing node and express)?
Also, is it possible to use meteorjs on the client side? If ever, what are key advantages and can it do direct access to mongodb as well?
Frontend accesing MongoDB is possible, via its HTTP (rest) interface
http://docs.mongodb.org/ecosystem/tools/http-interfaces/
To get the contents of a collection (note the trailing slash):
http://127.0.0.1:28017/databaseName/collectionName/
To add a limit:
http://127.0.0.1:28017/databaseName/collectionName/?limit=-10
To skip:
http://127.0.0.1:28017/databaseName/collectionName/?skip=5
To query for {a : 1}:
http://127.0.0.1:28017/databaseName/collectionName/?filter_a=1
Separate conditions with an &:
http://127.0.0.1:28017/databaseName/collectionName/?filter_a=1&limit=-10
Same as db.$cmd.findOne({listDatabase:1}) on the admin database in the shell:
http://localhost:28017/admin/$cmd/?filter_listDatabases=1&limit=1
To count documents in a collection:
http://host:port/db/$cmd/?filter_count=collection&limit=1
However, I personally discourage this approach. Node/Express can be a simple wrapper for auth/auth before you make any changes to DB.

Relationship of node.js / Express / Connect / Socket.io

I'm confused. The main question I have is, when to use pure node.js, when shall I use a framework/MVC like "express" or "connect".
I know that "express" is just adding a bunch of functionality to "connect", but what is it really good for? Lets say, I want all my HTTP stuff do against an "Apache" server and only do some partial stuff with node.js (like WebSocket connections, CouchDB, etc.).
Would it make sense in this scenario to use "express" or "connect" for some reason?
As far as I know, Socket.IO also handles HTTP requests as a fallback, so would it be just enough to use Socket.IO for those needs ?
What else is the big advantage using Express/Connect ?
Express (or Connect) is an application framework for HTTP web applications. It's the entry point of your application. It provides some very common functionnalities such as :
HTTP Server
URL Routing
Request args
Sessions
It also allows other functionnalities to be easily used (they are called middleware) such as Authentication handling, templating.
If you just want to implement a pub/sub service through SocketIO, without any pages or other API, just use the Socket.io library (S.io homepage example) :
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
If you want to use Socket.io within a more complexe application, serving pages and API, you can (must ?) integrate it with Express (see How To Use)
Hi I have been using Expressjs for some time now and find it particularly useful for the Jade templating engine it provides by default. Jade is a new templating language and though I admit it takes some time to get familiar with it, its pretty useful. You can write conditionals, mixins, pass variables to your pages, use partials etc. It just makes client side html really easy. Also expressjs sets up your view, javascript, stylesheets directory structure... If followed properly catching responses and rendering html pages are a matter of couple of line of codes. As discussed above, the http middlewear is a lot easier to implement..

Categories

Resources