I have problem with cache in Internet Explorer. In Chrome everything works fine. When I try to add item in my application then data doesn't refresh. I have to press Ctrl+R to refresh data.
I'm using:
NodeJS / express (backend)
AngularJS (frontend)
Jade (view engine)
MongoDB / mongoose (database)
Jade view:
form(name="AddPartner")
.col-md-4
|Name:
input.form-control(type='text', name='name' ng-model="dataPartner.name")
Script:
var myApp = angular.module('myApp', []);
myApp.controller("myCtrl", function($scope, $http){
$scope.loadPartnersData = function () {
$http.get("/main/partner-list").then(function(result) {
$scope.partnerList = result.data.partnerList;
});
};
$scope.loadPartnersData();
$scope.addPartner = function(data) {
$http.post(addPartner, data)
.then(function(response) {
console.log(response);
});
$scope.loadPartnersData();
window.alert("Done!");
};
My backend:
router.get('/partner-list', function (req, res) {
Partner.find({}, function (err, partnerList) {
if (err) throw err;
res.json({ partnerList: partnerList });
});
});
router.post('/addPartner', function (req, res) {
new Partner({ name : req.body.name, shared : req.body.shared }).save(function (err) {
if (err) console.log(err);
res.writeHead(200, { 'Content-Type': 'application/json' });
});
});
Write your response like res.json(response); and also move your $scope.loadPartnersData(); call inside the then portion of your promise. ;)
Related
I have an ExpressJS route as below:
var exec = require('child_process').exec;
app.get('/someURL', function (req, res) {
exec('cp file1 file2', (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
// the *entire* stdout and stderr (buffered)
console.log('stdout: ' + stdout);
console.log(stderr);
});
return stdout;
})
This is basically to run a CLI command when the user goes to the specified route on the web app.
In my AngularJS controller I have the following function:
function getData() {
let deferred = this.$q.defer();
this.$http({
method: 'GET',
url: '/someURL'
}).then((response) => {
deferred.resolve(response);
}, (error) => {
deferred.reject(error);
});
return deferred.promise;
}
this.getData().then(function(response) {
console.log(response);
}).catch(function(err) {
console.log(err, err.stack);
});
When I run the application, I am getting the html code as the response at console.log(response), instead of stdout. How do I correct that?
app.get('/someURL', function (req, res) {
// Here do the processing that you need to do
res.send('response');
})
In your expressJS server, you are intercepting the request but you are not sending anything back. You have to specifically send something back using the 'res' object from the funtion parameter. You can add http status codes too like
res.status('200').send(data);
I'm using xml2js with node.js to retrieve data from an API, but I would only like the code to run when the "/testpage" route is activated, which would then assign the api response to a variable and pass it along to a script on testpage.ejs where the end goal is to print the object/variable contents to the console.
The problem I'm facing is that I'm getting the "undefined" browser console response with the above code.
If I place the code outside of the route, have the response assigned to a variable and then pass that variable to the testpage script, then it works fine.
At this point I'm assuming it could be an asynchronous issue, but I'm not sure, or even how to tackle it if so.
// Node.js
const requestPromise = require('request-promise'),
xml2js = require('xml2js').parseString,
express = require("express"),
app = express();
const port = 3200,
apiURL = 'https://api.exampleapi.com';
app.set("view engine", "ejs");
app.use('/public', express.static(__dirname + "/public"));
app.get("/testpage", function(req, res){
var myApiObject; // To store api response
requestPromise.post(apiURL, (error, response, body) => {
if(error){
console.log(error);
return error;
}
}).then( (body) => {
xml2js(body, (err, result) => {
if(err){
console.log(err);
} else {
myApiObject = result;
return result;
}
});
});
res.render("testpage", {myApiObject: myApiObject});
});
app.listen(process.env.PORT || port, function(){
console.log("Server is running...");
});
<!--testpage.ejs-->
<html>
<head>
<title>
</title>
</head>
<body>
<p>This is the testpage</p>
<script>
var myObj =<%-JSON.stringify(myApiObject)%>
console.log(myObj);
</script>
</body>
Any ideas on what I'm doing wrong?
You need to render your page after the response from API call is received. Change your code like this:
requestPromise.post(apiURL, (error, response, body) => {
if(error){
console.log(error);
return error;
}
}).then( (body) => {
xml2js(body, (err, result) => {
if(err){
console.log(err);
} else {
res.render("testpage", {myApiObject: result});
return result;
}
});
});
I am serving a static webpage from Node.JS via Express webserver:
app.use('/', express.static('public'));
What is the most minimalistic way to integrate some dynamic content, e.g. a list of items that is retrieved from a database into such a page?
I see the possibility to "fake" a .js file on the server that is actually dynamically created and then loaded in an index.html that resides inside the public folder on the server:
app.get('/myScript.js', (req, res) => {
data = getDataFromDatabase();
res.send('var data1 = ' + data[0] + '; var data2 = ' + data[1]);
});
This seems extremely hacky and I wonder what the best minimalistic approach to this is.
You can also return a response from a callback inside of your get route. I do something like this:
Endpoint:
router.get('/people', (req, res) => {
People.list((error, response) => {
if (error) return res.end();
return res.send(response);
});
});
Model:
module.exports = {
connect: (callback) => {
r.connect({
host: config.db.host,
port: config.db.port,
db: config.db.name
})
.then((connection) => {
return callback(null, connection);
})
.error((err) => {
return callback(err);
});
},
list: function (callback) {
this.connect((err, connection) => {
if (err) return callback(err);
r.db(config.db.name).table(config.db.tables.people)
.run(connection)
.then((cursor) => {
return cursor.toArray();
})
.then((users) => {
return callback(null, users);
})
.error((err) => {
return callback(err);
});
});
},
...
With this then I get the response object printed to my screen. The model code is rethinkdb code, but you can substitute that with whatever you are using. Sorry if this wasn't quite what you were after. Best of luck with your build =)
So I have a MongoDB that I query using Node.js.
The data is not being sent out using this function and I dont know what is wrong
var findIco = function(db, callback) {
var cursor =db.collection('footIco').find();
cursor.each(function(err, doc) {
// console.log(err);
if (doc != null) {
console.log(doc); <------ DISPLAY THE DATA IN THE CONSOLE
} else {
callback();
}
});
};
app.get('/icons', function(req, res){
//calling the function
MongoClient.connect(url, function(err, db) {
if(err) {
console.log(err);
return res.status(500).send(err);
}
findIco(db, function(icons) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
console.log(icons);<--------------- IS UNDEFINED
res.json(icons);
db.close();
return;
});
});
});
app.listen(8080);
What am I doing wrong?
You would need to use some form of Web Server to create an API that will return this data when a request is received at a certain resource. You can make the requests to your API using the $http service in your Angular app. The most popular choice for a Node web framework is Express, this wraps the Node Core HTTP Module and gives a robust API.
Other Popular Node.js Web Frameworks
Koa
Hapi.js
These are just a couple of Node.js Web Frameworks, I also excluded any frameworks that are MVC based frameworks such as Meteor and Sails.js since Angular already is providing that piece.
To get up and running quickly in Express, you can use express-generator to scaffold out a basic Express API. Then just add a route for your function in your Node.js server.
findIco
var findIco = function(db, callback) {
db.collection('footIco').find().toArray(function(err, docs) {
if (err) return callback(err, null);
return callback(null, docs);
});
}
Node.js API
app.get('/icons', function getIcons(req, res){
//calling the function
MongoClient.connect(url, function(err, db) {
if(err) {
console.log(err);
return res.status(500).json(err);
}
findIco(db, function(err, icons) {
if (err)
res.status(500).json(err);
else {
if (!icons)
res.status(204).send();
else
res.json(icons);
}
db.close();
return;
});
});
});
Angular $http call in footIconCtrl
app.controller('footIconCtrl', ['$scope', '$http', function($scope, $http){
$scope.icons = [];
$http({
method: 'GET',
url: 'http://<serverAddress>:<serverPort>/icons'
})
.then(function(icons) {
$scope.icons = icons.data;
})
.catch(function(errRes) {
// Handle errRess
});
});
In your angular code, you will have a file like getDocument.controller.js with a function with an http call to your service. Something like this :
var getDocs = function(){
var apis = http://localhost:9000/api/getDocs;
httpRequest.get(apis).
then(function(docs){
// Your code to handle the response
});
};
Now in your server side code, you can send the response as
CollectionName.find({}, function (err, docs) {
if (err) return next(err);
if (!docs) return res.send(401);
res.json(docs);
});
I have only just started trying out NodeJS. Having a little experience with Angular, I thought of trying out a MEAN stack to-do app tutorial from scotch.
I understand what is happening and how angular, node and my view are supposed to be working together. But they just aren't. I've made sure not to miss anything. Here is my code.
Server.js is in the root folder
// server.js
// set up ========================
var express = require('express');
var app = express(); // create our app w/ express
var mongoose = require('mongoose'); // mongoose for mongodb
var mongodb = require('mongodb');
var morgan = require('morgan'); // log requests to the console (express4)
var bodyParser = require('body-parser'); // pull information from HTML POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)
// configuration =================
mongoose.connect('mongodb://<user>:<pass>#proximus.modulusmongo.net:27017/uwa8sIje'); // connect to mongoDB database on modulus.io
app.use(express.static(__dirname +'/public')); // set the static files location /public/img will be /img for users
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded({'extended':'true'})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(methodOverride());
// creating mongoose model ================================
var Todo = mongoose.model('Todo', {
text: String
});
// Todo is the mongo db. Creating API for CRUD in the db
//============================================================
app.get('/api/todos', function(req, res) {
Todo.find(function (err, todos) { //within 'get' we are looking for all the entries in the db
if(err) {
res.send(err) //checking for errors
}
res.json(todos); //response sends all listed todos in JSON
})
})
app.post('/api/todos', function(req, res) { //to post a new todo
Todo.create({ //creating a new post. information comes from AJAX request from Angular
text: req.body.text,
done: false
}, function(err, todo) { //checking errors
if(err) {
res.send(err);
}
Todo.find(function (err, todos) { //after post is added, find and display all existing todos again
if(err) {
res.send(err)
}
res.json(todos);
})
})
})
app.delete('/api/todos/:todo_id', function(req, res) { //delete a todo
Todo.remove({ //remove a todo from database
_id: req.params.todo_id, //todo id to be removed is provided by the request url(params)
}, function(err, todo) {
if(err) {
res.send(err);
}
Todo.find(function (err, todos) {
if (err) {
res.send(err)
}
res.json(todos);
})
})
})
//======================================================================
app.get('*', function(req,res) {
res.sendfile('./public/index.html') //load this single view file. angular will handle the
//page changes on the front end
})
// listen (start app with node server.js) ======================================
app.listen(8080);
console.log("App listening on port 8080");
My angular controller lies in the public folder along with my view
var Todoz = angular.module('Todoz', []);
function mainController($http, $scope) {
$scope.formData = {};
$http.get('/api/todos')
.success(function (data) {
$scope.todos = data;
console.log(data);
})
$scope.createTodo = function() {
$http.post('/api/todos', $scope.formData)
.success(function (data) {
$scope.formData = {};
$scope.todos = data;
})
.error(function (data) {
console.log('Error' + data)
})
}
$scope.deleteTodo = function(id) {
$http.delete('/api/todos/' + id)
.success(function (data) {
$scope.todos = data;
console.log(data);
})
.error(function (data) {
console.log(data)
});
};
Todoz.controller("mainController", mainController);
}
and my minimal view
<head>
<title>
To-Do-and-Node-To-Do
</title>
</head>
<body ng-app="Todoz">
<h1>The To-do-ist</h1>
<div ng-controller="mainController">
<div>
<input type="text" ng-model="formData.text"></input>
<button type="submit" ng-click="createTodo()">Submit</button>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="./core.js"></script>
</body>
When I start the server with 'nodemon server.js' my console logs a /GET request and the app shows on my port 8080. However when I try to post a new item from my text-box and expect it to console.log, it doesn't do anything. My browser console returns this
POST http://localhost:8080/api/todos net::ERR_CONNECTION_REFUSED angular.js:8632
Error core.js:23
POST http://localhost:8080/api/todos net::ERR_CONNECTION_REFUSED angular.js:8632
Error core.js:23
Please help. I have no clue what is going wrong.