Angular JS Express JS Node JS file upload issue - angularjs

Please help me
I'm new to this and for file upload I referred to this - http://goodheads.io/2015/06/22/handling-file-uploads-using-angularjs-node-and-express/
my implementation is given below. At place I have deleted things to make sure the post size is readable enough. The main problem is only file upload section other than that everything is working like a charm. Please help.
Here is the index.html section.
<!doctype html>
<html ng-app ="myApp">
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
</head>
<body>
<div class="container" ng-controller="AppCtrl">
<table width="500" border="2" cellspacing="2" cellpadding="2">
<form>
<tbody>
<tr>
<td><input type="file" ng-file-select="fileSelected($files)" accept="'image/*'"></td>
<td><input type="submit" ng-click="uploadFile()" ></td>
</tr>
</tbody>
</form>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script src="controller.js"></script>
<script type="text/javascript" src="../bower_components/ng-file-upload-shim/ng-file-upload-shim.js"></script>
<script type="text/javascript" src="../bower_components/ng-file-upload-shim/ng-file-upload.js"></script>
</body>
</html>
<form></form>
Here is the controller that is guiding the file.
var myApp = angular.module('myApp', ['angularFileUpload']);
myApp.controller('AppCtrl', ['$scope', '$http', 'upload', function($scope, $http, $upload) {
console.log("Hello World from controller");
$scope.addData = function()
{
console.log($scope.user);
console.log("whore");
$http.post('../addData', $scope.user).success(function(response) {
console.log(response);
});
$scope.fileSelected = function(files)
{
if (files && files.length) {
$scope.file = files[0];
}
$upload.upload({
url: '../upload',
file: $scope.file
})
.success(function(data) {
console.log(data, 'uploaded');
});
};
};
}]);
Please ignore the first function it is for something else but my problem is something else.
Now here is the server code where I have used multer to do the trick.
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var multer = require('multer');
var validator = require('node-mongoose-validator');
var bodyParser = require('body-parser')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }))
app.use(multer({
dest: './uploads/'
}));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
The server file is very big therefore I'm not adding all the routes and all section here. When I'm deleting the section which has the upload command it runs without error but when I am adding it, error is shown.
C:\nodefiles\new\node_modules\express\lib\application.js:209
throw new TypeError('app.use() requires middleware functions');
^
TypeError: app.use() requires middleware functions
at EventEmitter.use (C:\nodefiles\new\node_modules\express\lib\application.js:209:11)
at Object.<anonymous> (C:\nodefiles\new\server.js:9:5)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3

multer({dest: './uploads/'}) does not itself return a middleware function.
You have to use one of the functions of multer class to get a middleware function.
So you would end up using it like multer({...}).single(). The different functions are described here - https://github.com/expressjs/multer#singlefieldname.
Multer doc has good examples of the right usage: https://github.com/expressjs/multer#usage
To save a click, here is a full working example:
var multer = require('multer');
var upload = multer({
dest: __dirname + '/../../public/uploads/',
});
app.post('/api/data', upload.single('filenameInTheForm'), function (req, res, next) {
return res.ok();
});
Important to note that filenameInTheForm must match the field name in the multipart/form-data request.
Also, there is a slight difference in using app.use(..) and the way described above. app.use() will cause the middleware executed for every endpoint, lucky enough, if the content type is not multipart/form-data the middleware does nothing. To avoid slight overhead from the fact that it still performs the content type check, it is nicer to use it as in the example above.

Related

Angular UI-Routing is not loading my partial into the viewport

I have a Node.JS+Express backend, and am trying to set up an angular frontend.
I have a basic HTML template called common.html:
<!DOCTYPE HTML>
<html>
<head>
<title>Watson-Amadeus</title>
<link rel = "stylesheet" href = "css/index.css" />
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel = "script" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.min.js"></script>
<script src="js/amadeus.js"></script>
</head>
<body ng-app = "watson_amadeus">
<div ui-view>
</div>
</body>
</html>
js/amadeus.js then looks like
var app = angular.module("watson_amadeus", ["ui.router"]);
app.config(($stateProvider) => {
var introState = {
name: "intro",
url: "/intro",
templateUrl: "../index.html"
}
var amadeusState = {
name: "amadeus",
url: "/amadeus",
template: "../watson-amadeus.html"
}
$stateProvider.state(introState);
$stateProvider.state(amadeusState);
});
app.controller("amadeus_controller", ($scope) => {
$scope.messages = [
{text: "Yo"},
{text: "sup?"}
];
console.log("controller");
$scope.send_message = () => {
$scope.messages.push({text: $scope.msg_to_send});
$scope.msg_to_send = "";
};
});
intro.html and watson-amadeus.html are then just partials with some html in them. My Node server code looks like this:
var express = require('express'),
amadeus = require('./rest/amadeus.js'),
body_parser = require('body-parser');
var app = express();
app.use(body_parser.json());
app.use(body_parser.urlencoded({extended: false}));
app.use(express.static("public")); // Use static pages from the public directory
app.post("/api/amadeus/", amadeus.send_message);
app.get("*", (req, res) => {
res.sendFile(__dirname + "/public/common.html");
});
app.listen(8080); // Set the server to listen on port 8080
Finally, my directory structure is reasonably straightforward:
project_dir
public
js
amadeus.js
common.html
index.html
watson-amadeus.html
node_server.js
package.json
When I start the web server and try http://localhost:8080/intro, I am greeted with just a blank screen, and looking at the page source shows that it is just loading common.html without putting the index.html content into the viewport as it should. What is more; when I do http://localhost:8080/, I get the contents of index.html, but without the parts from common.html.
I'm new to angular, so this may be something fundamental but I don't know where I have messed up.
Once you defined app.use(express.static('public'));, express server will load index.html automatically, so app.get("*", (req, res) => { res.sendFile(__dirname + "/public/common.html"); }); won't run at all.
I would recommend rename common.html to index.html since it is your major html.
By default ui-route will add#! to url, try http://10.8.8.8:8080/, after index.html has been loaded successfully, the url actually changed to http://10.8.8.8:8080/#!/.
Hence, you can access your /intro by http://10.8.8.8:8080/#!/intro.
There will be lots of effort to take if you want to remove #!, you can research next step. Good luck!

Angular module not loading

So I am creating a new module with a single controller, saved in controllers directory off of the app directory:
var tables = angular.module('tables',[]).controller('setName', function ($scope) {
$scope.userName = userName;
$scope.userPassword = userPassword;
});
I have the following html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ang</title>
</head>
<script src="/socket.io-client/socket.io.js"></script>
<script src="/angular/angular.min.js"></script>
<body ng-app="tables">
<div ng-controller="setName">
User Name: <input type="text" ng-model="userName" ><br>
Password: <input type="text" ng-model="userPassword" ><br><br>
User Name: {{userName}}<br>
Password: {{userPassword}}<br>
</div>
</body>
</html>
I am using express to serve the page:
//Load express
var express = require('express');
//Load tables
//var tables = angular.module('table');
// Create express app
var app = express();
//Load http express wrapper
var http= require('http');
//Create variable for the port the server listens on
var srvPort = 3000;
//Make a static path to node_modules directory
app.use(express.static('node_modules'));
app.use(express.static('controllers'));
//Make a static path to the public directory
app.use(express.static('public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
var server = http.createServer(app).listen(srvPort, function () {
console.log('Server is listening on port ' + srvPort);
});
require('./public/javascript/sockets.js').initialize(server);
I get the following error:
Failed to instantiate module tables due to:
Error: [$injector:nomod] http://errors.angularjs.org/1.5.0/$injector/nomod? p0=tables
at Error (native)
at http://localhost:3000/angular/angular.min.js:6:416
at http://localhost:3000/angular/angular.min.js:25:136
at b (http://localhost:3000/angular/angular.min.js:24:188)
at http://localhost:3000/angular/angular.min.js:24:431
at http://localhost:3000/angular/angular.min.js:39:287
at n (http://localhost:3000/angular/angular.min.js:7:355)
at g (http://localhost:3000/angular/angular.min.js:39:135)
at fb (http://localhost:3000/angular/angular.min.js:43:164)
at Ac.c (http://localhost:3000/angular/angular.min.js:20:449
So my question is, why is my module not loading?
Any help would be appreciated!
Z
You're not loading it in <head>. You have only socket.io.js and angular.min.js but not the JS file containing your module.

Node JS and AngularJS - script not found - 404

I am trying to build a simple "Hello world" Node.js/AngularJS app and am struggling. I am running the app through localhost and struggling to figure out why the HTML page isn't finding my script files.
server.js
var express = require('express');
var fs = require('fs');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/app');
app.set('view engine', 'ejs');
app.get('/', function(request, response) {
response.render('index');
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
The server is being run successfully. The angularJS application is listed below:
index.ejs
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="app.js"></script>
<script src="Controllers/home.ctrl.js"></script>
</head>
<body ng-app>
<div ng-view></div>
</body>
</html>
app.js
angular.module("app", ["ngRoute"])
.config(function($routeProvider){
$routeProvider
.when("/", {
controller: "HomeController",
templateUrl: "app/Views/home.html"
});
});
home.html
home.ctrl.js
Folder structure:
Web server
index.js
app
Controllers
Views
app.js
index.ejs
The error I am getting in the console:
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
GET - http://localhost:5000/app.js
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
GET - http://localhost:5000/Controllers/home.ctrl.js
The problem is here:
<script src="app.js"></script>
<script src="Controllers/home.ctrl.js"></script>
<script src="app/app.js"></script>
You include two app.js, one of them has the wrong path. Maybe you meant index.js instead.
UPDATE
I see another problem here:
app.use(express.static(__dirname + '/public'));
You serve the folder public, but those files are in app

AngularJS. $resource, MongoLab, Restful API - What's wrong with my sample?

I am new to AngularJS and loving it as I learn it. I am trying to figure out how to communicate with MongoLab from AngularJS using $resource and RESTful API. I have the following two files:
index.html:
-----------
<!DOCTYPE html>
<html lang="en">
<head>
<title>MongoLab Connectivity Test</title>
<script src="angular.js"></script>
<script src="angular-resource.js"></script>
<script src="app3.js"></script>
<link rel="stylesheet" href="bootstrap.css" />
<link rel="stylesheet" href="bootstrap-theme.css" />
</head>
<body ng-app="myModule">
<div ng-controller="display">
<p>{{data.message}}</p>
</div>
</body>
</html>
app3.js:
--------
var myModule = angular.module('myModule', ['ngResource']);
myModule.controller('display', function($scope, personService) {
$scope.data = personService.query();
});
myModule.constant({
DB_BASEURL: "https://api.mongolab.com/api/1/databases/db1/collections",
API_KEY: "<MyAPIKey>"
})
myModule.factory('personService', ['$resource', 'DB_BASEURL', 'API_KEY',
function($resource, DB_BASEURL, API_KEY)
{
return $resource
(DB_BASEURL+'/persons/:id'
,{id: "#id" apiKey: API_KEY}
);
}
]);
When I try it, I get the following output:
{{data.message}}
I am not sure what I am doing wrong. Hoping to get some help.
A better way to connect would be : https://github.com/pkozlowski-opensource/angularjs-mongolab
[copying the text from documentation AS IT IS]
Usage instructions
Firstly you need to include both AngularJS and the angular-mongolab.js script : https://raw.githubusercontent.com/pkozlowski-opensource/angularjs-mongolab/master/src/angular-mongolab.js
Then, you need to configure 2 parameters:
MongoLab key (API_KEY)
database name (DB_NAME)
Configuration parameters needs to be specified in a constant MONGOLAB_CONFIG on an application's module:
var app = angular.module('app', ['mongolabResourceHttp']);
app.constant('MONGOLAB_CONFIG',{API_KEY:'your key goes here', DB_NAME:'angularjs'});
Then, creating new resources is very, very easy and boils down to calling $mongolabResource with a MongoDB collection name:
app.factory('Project', function ($mongolabResourceHttp) {
return $mongolabResourceHttp('projects');
});
As soon as the above is done you are ready to inject and use a freshly created resource in your services and controllers:
app.controller('AppController', function ($scope, Project) {
Project.all().then(function(projects){
$scope.projects = projects;
});
});
Also, you may check out the blog here for even simpler implementation : http://asad.io/angularjs-with-mongolab/
Use the $http module by Angular and Mongolab REST API
For GET request,
$http.get('https://api.mongolab.com/api/1/databases/DATABASE_NAME/collections/COLLECTION_NAME?apiKey=YOUR_API_KEY')
.success(function(data) {
console.log(data)
}
For POST request,
$http.post('https://api.mongolab.com/api/1/databases/DATABASE_NAME/collections/COLLECTION_NAME?apiKey=YOUR_API_KEY', $scope.data, {
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
})
.success(function() {
console.log('Data saved successfully')
}
More on http method support documentation - http://docs.mongolab.com/data-api/#reference

Maintaining server side API urls in Javascript application

I'm building a modular javascript application (RequireJS/Backbone), and am looking for some advice on best practices for propagating server-side URLs into the JS application for use in client side templating, API requests, etc.
Inject it into the base template that kicks off the Javascript application?
API request specifically for this purpose?
Would love to hear solutions others have used. Thanks!
You can render a <script> tag in the body, define a module and put your URLs there in any way you like.
After that you can require it inside your modules (.js files).
HTML (e.g. your application layout):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inline RequireJS define</title>
</head>
<body>
<h1 id="foo-holder"></h1>
<a id="sign-up-link" href="#"></a>
<script>
// This is rendered by your server-side application:
define('data/config', function(require, exports, module) {
exports.Url = {
HOME: 'https://mysite.com',
SIGN_IN: 'https://mysite.com/sign-in',
SIGN_UP: 'https://mysite.com/sign-up',
LOG_OUT: 'https://mysite.com/log-out'
};
exports.foo = 'bar';
});
</script>
</body>
</html>
JavaScript (somewhere in your module):
// This is somewhere in your JavaScript module
require(['data/config'], function(Config) {
$('#foo-holder').text(Config.foo);
$('#sign-up-link')
.text(Config.Url.SIGN_UP)
.attr('href', Config.Url.SIGN_UP);
});
DEMO
Another trick could be done with some kind of attribute-binding.
In your layout:
<a data-url="HOME" href="#">Home</a>
<a data-url="SIGN_IN" href="#">Sign In</a>
<a data-url="SIGN_UP" href="#">Sign Up</a>
<a data-url="LOG_OUT" href="#">Log Out</a>
<script>
// This is rendered by your server-side application:
define('data/config', function(require, exports, module) {
exports.Url = {
HOME: 'https://mysite.com',
SIGN_IN: 'https://mysite.com/sign-in',
SIGN_UP: 'https://mysite.com/sign-up',
LOG_OUT: 'https://mysite.com/log-out'
};
exports.foo = 'bar';
});
</script>
In your JavaScript file:
// This is somewhere in your JavaScript module
require(['data/config'], function(Config) {
$('a[data-url]').each(function() {
var $a,
urlConstant,
url;
$a = $(this);
urlConstant = $a.data('url');
url = Config.Url[urlConstant];
if(url) {
$a.attr('href', url);
}
});
});
DEMO

Resources