Getting Information From Mongo And Displaying It With AngularJS - node.js

Hello I am trying to learn the mean stack and seem to be stuck.
I created a node.js, express angular and mongo project.
I have installed mongo with npm install mongodb
How do I pass data from mongo to the angular view?
my index.ejs file looks like this
<!DOCTYPE html>
<html ng-app="phonecatApp">
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="/javascripts/countriesCtrl.js"></script>
<script src="/javascripts/angular.min.js" ></script>
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<div ng-controller="PhoneListCtrl">
<table border="1" cellspacing="0" cellpadding=3>
<tr><td>Abbreviation</td><td>Name</td></tr>
<tr ng-repeat="state in states">
<td>{{state.abbreviation}}</td><td>{{state.name}}</td>
</tr>
</table>
</div>
</body>
</html>
my countriesCtrl.js looks like this
var MongoClient = require('mongodb').MongoClient;
//var mongoClient = new MongoClient(new Server('localhost', 27017));
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function ($scope) {
$scope.lkp_states = function() {
MongoClient.connect("mongodb://localhost:27017/website", function(err, db) {
if(err) {
return console.dir(err);
}
else
{
console.log("connected to mongo");
}
})
return db.collection('states');
}
});
The error I get is this
GET http://localhost:3000/ [HTTP/1.1 200 OK 35ms]
Use of getUserData() or setUserData() is deprecated. Use WeakMap or element.dataset instead. requestNotifier.js:63
GET http://localhost:3000/stylesheets/style.css [HTTP/1.1 304 Not Modified 17ms]
GET http://localhost:3000/javascripts/countriesCtrl.js [HTTP/1.1 304 Not Modified 15ms]
GET http://localhost:3000/javascripts/angular.min.js [HTTP/1.1 304 Not Modified 7ms]
ReferenceError: require is not defined countriesCtrl.js:2
http://localhost:3000/javascripts/angular.min.js is being assigned a //# sourceMappingURL, but already has one
Error: [$injector:modulerr] http://errors.angularjs.org/1.2.21/$injector/modulerr?p0=phonecatApp&p1=%5B%24injector%3Anomod%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.2.21%2F%24injector%2Fnomod%3Fp0%3DphonecatApp%0Ay%2F%3C%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A6%3A443%0AZc%2Fb.module%3C%2F%3C%2Fb%5Be%5D%3C%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A20%3A385%0AZc%2Fb.module%3C%2F%3C%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A20%3A273%0Ae%2F%3C%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A33%3A206%0Aq%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A7%3A288%0Ae%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A33%3A148%0Agc%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A36%3A250%0Afc%2Fc%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A18%3A58%0Afc%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A18%3A270%0AXc%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A17%3A369%0A%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A213%3A58%0Aa%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A144%3A399%0Aoe%2Fc%2F%3C%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A31%3A159%0Aq%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A7%3A288%0Aoe%2Fc%40http%3A%2F%2Flocalhost%3A3000%2Fjavascripts%2Fangular.min.js%3A31%3A143%0A angular.min.js:6
GET http://localhost:3000/stylesheets/style.css

The MongoClient uses require.js, which is a common way to include libraries in node.js. In this case, however, you aren't running this code on the server in node.js, you are running it on the client in the browser, and thus don't have require.js defined by default.
You have three options to solve this situation:
Include require.js and register it as a script in your HTML.
Load the MongoClient manually by using a <script> tag in your HTML and using the new MongoClient() function.
Refactor your application to perform the Mongo Database access at the server level in node.js and only have your client HTML perform a request for the query results rather than perform the query itself. (recommended)

Related

Ejs doesn't load when I call a function from another file

Basicly I want to run a function when I clicked the button, but it works when I started the server and go to localhost one time, here's what's supposed to happen, after that localhost page doesn't load. (Unable to connect error)
If I remove the function there is no problem. How can I get it to work only when I click the button ?
Many thanks.
My func.js
const mongoose = require("mongoose");
const axios = require('axios');
async function func() {
//MyCodes
}
module.exports = {
func: func
}
My index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button type="button" onClick= <%= func.func() %> >Click</button>
//Other codes are independent the button
</body>
</html>
My res.render codeblocks in app.js
var func = require('./func');
app.get("/", (req, res) => {
res.render('index', {
cName: name,
symbol: symbol,
len: finds[0].result.length,
cPrice: price,
cDate: date,
func:func
});
});
});
})
You are misunderstanding. You cannot call an internal nodejs function(backend) from the html (frontend). If your frontend need to execute some backend operation like query to mongo, you have these options:
#1 client side rendering (Modern)
This is the most used in the modern world: Ajax & Api
your backend exposes a rest endpoints like /products/search who recieve a json and return another json
this endpoints should be consumed with javascript on some js file of your frontend:
html
<html lang="en">
<head>
<script src="./controller.js"></script>
</head>
<body>
<button type="button" onClick="search();" >Click</button>
</body>
</html>
controller.js
function search(){
$.ajax({
url:"./api/products/search",
type:"POST",
data:JSON.stringify(fooObject),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(response){
...
}
})
}
Note 1: controller.js contains javascript for browser not for backend : nodejs
Note 2: ejs is only used to return the the initial html, so it is better to use another frameworks like:react, angular, vue
#2 server side rendering (Legacies)
In this case, ajax and js for browser are not strictly required.
Any event on your html should use <form> to trigger an entire page reload
You backend receives any parameter from the , make some operations like mongo queries and returns html instead json, using res.render in your case
Note
Ejs is for SSR = server side rendering, so add ajax could be complex for novices. In this case, use the option #2
You cannot use a nodejs function (javascript for server) in the client side (javascript for browser). Maybe some workaround are able to do that but, don't mix different things.

Uncaught reference error require is not defined

I'm trying to use an html page in order to test the connection with my server.
I've got no problem with my server.js
var http = require('http');
var url = require("url");
// Chargement de socket.io
var io = require('socket.io').listen(server);
var server = http.createServer(function(req, res) {
var page = url.parse(req.url).pathname;
// Quand un client se connecte, on le note dans la console
});
io.sockets.on('connection', function (socket) {
console.log('Un client est connecté !');
});
server.listen(8080);
My client should is an html page here
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.io</title>
</head>
<body>
<h1>Communication test with socket.io !</h1>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://localhost:8000/server_node/node_modules/socket.io/lib/socket.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
</script>
</body>
</html>
Problem is, when I load the html client, I've got this error
socket.js:6 Uncaught ReferenceError: require is not defined
at socket.js:6
I'm not trying to implement a real client, I just want a simple page in order to do some connection test.
Thanks for your help
EDIT: Problem fixed, it was all because I wasn't loading the html file from the serverlike this fs.readFile('./ClientTest.html', 'utf-8', function(error, content) {
As this is just used to do some test, it's fine if it works this way; the client side will be with an other platform.
Sorry for that useless issue :(
You appear to be importing the server-side library on the client, you want to be importing the client-side one.
As per the docs, this is automatically served when socket.io runs on the server which you can import via
<script src="/socket.io/socket.io.js" />

Node.js jsdom set document root

I am trying to load local javascripts with jsdom.
Now I am wondering how I can make jsdom loading the javascripts from "__dirname/../public".
Can someone help me?
My current code is:
var fs = require('fs');
var jsdom = require('jsdom');
jsdom.defaultDocumentFeatures = {
FetchExternalResources: ["script"],
ProcessExternalResources: ["script"],
MutationEvents : '2.0',
QuerySelector : false
};
exports.test = function(req, res) {
var html = fs.readFileSync(__dirname+'/../public/html/lame.html');
var document = jsdom.jsdom(html, null, {documentRoot: __dirname+'/../public/'});
var window = document.createWindow();
window.addEventListener('load', function () {
//window.$('script').remove();
//window.$('[id]').removeAttr('id');
res.send(window.document.innerHTML);
window.close();
});
}
The simple HTML page is:
<html>
<head>
<title id="title">bum</title>
<script type="text/javascript" src="/javascripts/jquery.min.js"></script>
<script type="text/javascript" src="/javascripts/stuff.js"></script>
</head>
<body>
<h1>hello world</h1>
<h2 id="bam">XXX</h2>
</body>
</html>
I've run into the same issue and got it to work. Try these, in order:
documentRoot is not documented. The option which is documented is url. So replace documentRoot with url.
If the above is not enough, then add a base element. I've set my templates like this:
<head>
<base href="#BASE#"></base>
<!-- ... -->
</head>
where #BASE# is replaced with the same value as the one passed to url.
The solutions above are extracted from actual code in use in a test suite.

Testing NodeJS with Mocha - "Require is not defined"

I've been having trouble setting up a test framework for a NodeJS + Backbone app with the constant "require is not defined" error. I finally got it working using an in-browser test framework which picks up all of the dependencies I need and running a test.js file.
Currently, I'm only doing basic testing of my Backbone models, views, and collections. Now, I want to add in API testing but I'm back to the same "require is not defined" error. What is causing this? It's clear that I'm missing something fundamental here. I just want to add:
var request = require('supertest')
, express = require('express');
var app = express();
Snippet of test.js:
describe('Application', function(){
it("creates a global variable for the namespace", function() {
should.exist(App);
})
});
describe('Models', function() {
describe('SearchFormModel', function() {
beforeEach(function() {
this.SearchFormModel = new App.Model.SearchFormModel();
this.defaultFields = this.SearchFormModel.attributes;
})
it("created a SearchFormModel", function() {
should.exist(this.SearchFormModel);
})
it("should have 7 default fields", function() {
Object.keys(this.SearchFormModel).length.should.equal(7);
})
it("should default all fields to empty string", function() {
for (var key in this.defaultFields) {
this.defaultFields[key].should.equal("");
}
})
});
});
test-runner.html:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Title & Meta -->
<title>Frontend tests</title>
<meta charset="utf-8">
<!-- Stylesheets -->
<link rel="stylesheet" href="../node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<!-- Testing Libraries -->
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script>
// Use the expect version of chai assertions - http://chaijs.com/api/bdd
var should = chai.should();
// Tell mocha we want TDD syntax
mocha.setup('tdd');
</script>
<!-- Libs -->
<script src="../public/lib/jquery-1.8.2.min.js"></script>
<script src="../public/lib/underscore-min.js"></script>
<script src="../public/lib/backbone-min.js"></script>
<script src="../public/lib/bootstrap.min.js"></script>
<script src="../public/lib/highcharts.js"></script>
<script src="../public/lib/bootstrap-datepicker.js"></script>
<script src="../public/js/modules/exporting.js"></script>
<!-- Source files -->
<script src="../public/js/namespace.js"></script>
<script src="../public/js/jst.js"></script>
<script src="../public/js/utils.js"></script>
<script src="../public/js/models/models.js"></script>
<script src="../public/js/models/search.js"></script>
<script src="../public/js/models/plot.js"></script>
<script src="../public/js/models/search_result.js"></script>
<script src="../public/js/views/header.js"></script>
<script src="../public/js/views/plot.js"></script>
<script src="../public/js/views/list.js"></script>
<script src="../public/js/views/search.js"></script>
<script src="../public/js/router.js"></script>
<script src="../public/js/app.js"></script>
<!-- Test -->
<script src="test.js"></script>
<script>
mocha.run();
</script>
</body>
</html>
require and commonjs only works in Node.js
If you run Browser test, then you need to code it like you'll run it in the browser. Also note that Unit Test should be done in isolation, you shouldn't need to load you app server (express) to run your test.
I'd like to point you to an easy solution from there, but there's just too many choices. Very basically, you should start running browser test in the browser by loading an html file.
Then, you'll want to automatize this and run browser test from the terminal. That's when you want to run test in PhantomJs and the likes and output browser results on the terminal. Around this, you can checkout Karma and Testem who're two browser test runner (remember here Mocha alone won't run browser test via command line).
As you're using Backbone, you might be interested in the Backbone-Boilerplate Karma + Grunt test setup as a starting point. See more on this here: https://github.com/backbone-boilerplate/backbone-boilerplate

now.js - Hello World example - "require not defined"

I'm having trouble getting the now.js chat client tutorial to work. (I've also followed this video almost exactly).
server.coffee:
fs = require 'fs'
http = require 'http'
now = require 'now'
server = http.createServer (req, res) ->
fs.readFile(
'index.html'
(err, data) ->
res.writeHead(
200
'Content-Type': 'text/html'
)
res.end(data)
)
server.listen 8080
everyone = now.initialize(server)
everyone.now.distributeMessage = (msg) ->
everyone.now.receiveMessage(#.now.name, msg)
index.html:
<html>
<head>
<title>nowjs title</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/Flotype/now/master/lib/now.js"></script>
<script type="text/javascript">
$(document).ready(function() {
now.name = prompt("What's your name?", "");
now.receiveMessage = function(name, msg) {
return $("<div></div>").text("" + name + ": " + msg).appendTo("#msg");
};
return $("#send-button").click(function() {
now.distributeMessage($("#text-input").val());
return $("#text-input").val("");
});
});
</script>
</head>
<body>
<div id="msg"></div>
<input type="text" id="text-input">
<input type="button" value="Send" id="send-button">
</body>
</html>
When I load up the server with node server.js,
I get an error that says "require not defined" on line 1 of now.js. Consequently, the client side code can't find the variable 'now'.
I understand that 'require' is a node function, but how do I get the client to understand that?
Any help will be appreciated.
The file you're including in your client source (../Flotype/now/master/lib/now.js) is the Node server side code that is included in your node process when calling now = require 'now'.
So changing your included client source file from .../Flotype/now/master/lib/now.js to /nowjs/now.js will fix your problem.
Where does this /nowjs/now.js file come from?
When using NowJS (and many other npm packages that do client/server communication) you extend the server object. This is done with the line everyone = now.initialize(server) (Code Here).
What the initialize function does is wrap your server with the fileServer (Code Here) class in NowJS. This adds a resource under the "folder" nowjs which serves the client now.js file.
I got this error when trying to run nodejs file with js command instead of node.
Eg: if the nodejs file name is test.js, I was doing
js test.js
instead of
node test.js
I hope this helps too for people searching for this error.

Resources