I use the MEAN-Stack to upload images with tags.
While posting is working for me I cant get the form data for my updating/put part. I'm stuck at this part here in my routes file:
router.put('/update/:uuid/:filename', upload.single(), function (req, res, next) {
// console.log("_______________________req.FILES_______________________________________");
// console.log(req.files);
// console.log("_______________________req_______________________________________");
// console.log(req);
console.log("_______________________req.BODY_______________________________________");
console.log(req.body);
console.log(req.user);
Upload.findOneAndUpdate({
'file.filename': req.params.uuid,
'file.originalname': req.params.filename
}, {
// $set: {
// tags: req.body.tags
// }
},
function (err, upload) {
if (err) next(err);
else {
res.send(upload);
}
});
});
I I get something like this in the console.
_______________________req.BODY_______________________________________
{ '0': { _id: '593bff833ffbe41a523d03ad',
name: 'asdasdasd',
tags: { info: 'TestTag, Bla' },
created: '2017-06-10T14:17:39.501Z',
file:
{ fieldname: 'file',
originalname: 'ZzpXc6c.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'uploads/',
filename: '6fca88b03e88b7e72a751d7a44e9ed04',
path: 'uploads/6fca88b03e88b7e72a751d7a44e9ed04',
size: '303915' },
__v: '0',
'$hashKey': 'object:4' } }
This is the form
<div ng-controller="formCtrlUpdate" id="example-form" action="#">
<h2>Update</h2>
<ul>
<li ng-repeat="upload in image">
<a ng-href='{{upload.file.path + "/" + upload.file.originalname}}'>{{upload.file.originalname}}</a></br>
<img ng-src='{{upload.file.path + "/" + upload.file.originalname}}' />
<form ng-submit="submit()">
<legend>Update file here:</legend>
<label for="name">Name:</label>
<input type="text" name="name" id="name" ng-model="upload.name" />
<br/>
<label for="CreatorArtist">Artist:</label>
<input type="text" name="CreatorArtist" id="CreatorArtist" class="demo-default" ng-model="upload.tags.CreatorArtist" />
<br/>
<label for="info">Image Description:</label>
<input type="text" name="info" id="info" ng-model="upload.tags.info" />
<br/>
<input type="submit" value="Update" />
</form>
</li>
</ul>
</div>
FYI this ist the working Uploading part
Routes
router.post('/', upload.single('file'), function (req, res, next) {
console.log(req.body);
var newUpload = {
name: req.body.name,
tags: req.body.tags,
created: Date.now(),
file: req.file
};
Upload.create(newUpload, function (err, next) {
if (err) {
next(err);
} else {
res.send(newUpload);
}
});
});
Upload Form
<div ng-controller="formCtrl">
<h2>Upload</h2>
<h1>Ein Test Upload</h1>
<form ng-submit="submit()">
<legend>Upload a new file here:</legend>
<label for="name">Name:</label>
<input type="text" name="name" id="name" ng-model="upload.name" required/>
<br/>
<label for="CreatorArtist">Artist:</label>
<input type="text" name="CreatorArtist" id="CreatorArtist" class="demo-default" ng-model="upload.tags.CreatorArtist" required/>
<br/>
<label for="info">Image Description:</label>
<input type="text" name="info" id="info" ng-model="upload.tags.info" required/>
<br/>
<label for="file">File:</label>
<input type="file" class="imgInp" name="file" id="file" ng-model="upload.file" ngf-select ngf-max-size="25MB" required/>
<br/>
<input type="submit" value="Submit" />
</form>
</div>
and the controller
var app = angular.module('fileUpload', [
'ngFileUpload',
'ngResource',
'ngRoute'
]);
app.config(function ($routeProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$routeProvider.
when('/', {
templateUrl: '../views/home.html'
}).
when('/uploadForm', {
templateUrl: '../views/uploadForm.html'
}).
when('/updateForm', {
templateUrl: '../views/updateForm.html'
}).
otherwise('/');
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
$scope.submit = function () {
// console.log($scope.upload)
Upload.upload({
url: '/uploads',
method: 'post',
data: $scope.upload
}).then(function (response) {
console.log(response.data);
$scope.all.push(response.data);
$scope.upload = {};
console.log("Uploaded")
})
}
}]);
app.controller('formCtrlUpdate', ['$http', 'Upload', '$scope', '$routeParams', function ($http, Upload, $scope, $routeParams) {
console.log($routeParams);
$http.get('/uploads/update/' + $routeParams.uuid + '/' + $routeParams.filename).then(function (response) {
console.log(response.data);
$scope.image = response.data;
console.log("Beginning");
});
$scope.submit = function () {
console.log($scope.image)
// console.log("Update")
Upload.upload({
url: '/uploads/update/' + $routeParams.uuid + '/' + $routeParams.filename,
method: 'put',
// data: {
// _method: 'PUT',
// data: $scope.image
// }
data: $scope.image
}).then(function (response) {
// console.log(response.data);
$scope.all.push(response.data);
// $scope.image = {};
console.log("Update")
})
}
}]);
My question is now how can I get the form data in my req.body? Something like req.body.0 is not possible. With which parameters I can access something like in my POST/Upload part?
You can get the form data using req.body[0] It will display all the form data which you passed when you click update button .
Result:
{ _id: '593bff833ffbe41a523d03ad',
name: 'asdasdasd',
tags: { info: 'TestTag, Bla' },
created: '2017-06-10T14:17:39.501Z',
file:
{ fieldname: 'file',
originalname: 'ZzpXc6c.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'uploads/',
filename: '6fca88b03e88b7e72a751d7a44e9ed04',
path: 'uploads/6fca88b03e88b7e72a751d7a44e9ed04',
size: '303915' },
__v: '0',
'$hashKey': 'object:4'
}
or
if you want to get specific field like name you can use req.body[0].name
Related
I'm following an old Pluralsight tutorial that is no longer updated and have hit a wall: I am using Visual Studio 2013 and Angular JS v1.4, and have to use this tutorial as we are using this version of AngularJS at work.
HTML TEMLPLATE: NewEvent.html
<div style="padding-left:20px; padding-right: 20px">
<div class="container">
<h1>New Event</h1>
<hr />
<form name="newEventForm">
<fieldset>
<label for="eventName">Event Name:</label>
<input id="eventName" type="text" required ng-model="event.name" placeholder="Name of your event..." />
<label for="eventDate">Event Date:</label>
<input id="eventDate" type="text" required ng-pattern="/\d\d/\d\d/\d\d\d\d/" ng-model="event.date" placeholder="format (mm/dd/yyyy)..." />
<label for="eventTime">Event Time:</label>
<input id="eventTime" type="text" required ng-model="event.time" placeholder="Start and end time..." />
<label for="eventLocation">Event Location:</label>
<input id="eventLocation" type="text" required ng-model="event.location.address" placeholder="Address of event..." />
<br />
<input id="eventCity" type="text" required ng-model="event.location.city" class="input-small" placeholder="City..." />
<input id="eventProvince" type="text" ng-model="event.location.province" class="input-small" placeholder="Province..." />
<div>{{event.name}}</div>
<label for="eventImageUrl">Image:</label>
<input id="eventImageUrl" type="url" ng-model="event.imageUrl" class="input-xlarge" placeholder="Url of image..." />
</fieldset>
<img ng-src="{{event.imageUrl}}" src="" />
<br />
<br />
<button type="submit" ng-disabled="newEventForm.$invalid" ng-click="saveEvent(event, newEventForm)" class="btn btn-primary">Save</button>
<button type="button" ng-click="cancelEdit()" class="btn btn-default">Cancel</button>
</form>
</div>
CONTROLLER: EditEventController.js
'use strict'
eventsApp.controller('EditEventController',
function EditEventController($scope, eventData) {
$scope.event = {};
$scope.saveEvent = function (event, newEventForm) {
if (newEventForm.$valid) {
eventData.save(event)
.$promise
.then(function (response) { console.log('success', response) })
.catch(function (response) { console.log('failure', response) });
}
};
$scope.cancelEdit = function () {
window.location = "./EventDetails.html";
}
});
SERVICE: EventData.js
eventsApp.factory('eventData', function ($resource) {
var resource = $resource('data/event/:id.json', { id: '#id' }, { "getAll": { method: "GET", isArray: true, params: { something: "foo" } } });
return {
getEvent: function () {
return resource.get({ id: 1 });
},
save: function (event) {
event.id = 999;
return resource.save(event);
}
}
});
I had to specify '.json' in the var resource line and that's the only change I made to the code given by the tutors, because another page (which uses the getEvent function in the service) wouldn't work unless I did that.
When I click save, I get the 'failure' response in the console even though the model for the event has built correctly.
Screenshot of error in console:-
File structure:-
The 404 error appears to be attached to the save destination, even though as far as I can tell the URL is correct. How do I correctly use ngresource.save to save this file?
web-server.js - check get & post path
const express = require('express');
const path = require('path');
const events = require('./eventsController');
const app = express();
const rootPath = path.normalize(__dirname + '/../');
const bodyParser = require('body-parser');
const port = 8000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(rootPath + '/app'));
app.get('/data/event/:id', events.get);
app.post('/data/event/:id', events.save);
app.listen(port, function () {
console.log('Listening on port ' + port + '...');
});
EventData.js - check at the resource path
'use strict';
eventsApp.factory('eventData', function ($resource) {
var resource = $resource('/data/event/:id', { id: '#id' });
return {
getEvent: function () {
return resource.get({ id: 2 });
},
save: function (event) {
event.id = 999;
return resource.save(event);
}
};
});
<form name="reviewForm" ng-submit="Submit();" novalidation>
<div>
<div class="label label-primary first">Your Review:</div>
<div class="form-group has-error second">
<textarea id="Description" name="Description" ng-minlength=50 ng-maxlength=200 ng-model="Description" ng-required="true" style="width: 500px; height: 200px;"></textarea>
<label class="control-label" ng-show="submitted && reviewForm.Description.$error.required">Description is required.</label>
<label class="control-label" ng-show="submitted && reviewForm.Description.$error.minlength">Description is should not be less than 50 charecters.</label>
<label class="control-label" ng-show="submitted && reviewForm.Description.$error.maxlength">Description is should not be more than 200 charecters.</label>
</div>
<div style="clear:both;"></div>
</div>
<div>
<div>
<button type="submit" class="btn btn-primary" name="btnSubmit" ng-disabled="reviewForm.$invalid" ng-click="submitted=true">Submit</button>
</div>
</div>
</form>
$scope.Submit = function () {
var product = {
Title: $scope.Title,
description: $scope.Description,
name: $scope.Name,
Rating: 3
}
var res = $http({
url: "http://localhost:44826/api/review",
method: "POST",
data: $.param(product),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
});
res.success(
function (data, status, headers, config) {
//console.error('Repos error', status, data);
$scope.isVisible = false;
$scope.FeedMsg = true;
$scope.SuccessMsg = "Feedback has been submitted Sucessfully...";
});
res.error(function (data, status, headers, config) {
alert('error');
});
}
When I entered text in textarea below 50 or above 200 characters, it is showing error message but the form is submitting while clicking on submit button.
If I didn't enter anything form is not getting submitted to the server show error message.
I want the form not to submit on click of submit when error messages are showing...
Try this code:
HTML:
Pass the form name as a parameter in your Submit() function.
E.g.
<form name="reviewForm" ng-submit="Submit(reviewForm);" novalidation>
...
</form>
JS:
Add a condition if the form is valid.
E.g.
$scope.Submit = function(reviewForm) {
if (reviewForm.$valid) {
var product = {
Title: $scope.Title,
description: $scope.Description,
name: $scope.Name,
Rating: 3
};
var res = $http({
url: "http://localhost:44826/api/review",
method: "POST",
data: $.param(product),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
});
res.success(
function(data, status, headers, config) {
//console.error('Repos error', status, data);
$scope.isVisible = false;
$scope.FeedMsg = true;
$scope.SuccessMsg = "Feedback has been submitted Sucessfully...";
});
res.error(function(data, status, headers, config) {
alert('error');
});
}
};
Hope this helps.
Some what new to the MEAN stack. Currently I'm reworking an small app I did through codeschool to be full MEAN stack.
The app created can be seen here
Code School app
In rewriting the app using the MEAN stack after submitting the form I must refresh the page to see the city added to the list. What do I need to fix so I don't need to refresh the page for the new Item to be added to the list?
If I'm missing any relevant code below here is my git hub link
git hub link
Here is my code:
angular.module('Cityapp').controller('CityIndexController', function(City, $scope){
$scope.cities = City.query();
window.sc = $scope;
});
angular.module('Cityapp').controller('CityCreateController', function(City, $scope, $http){
$scope.city = new City();
$scope.saveCity = function(city){
$http({
method: 'POST',
url: '/city',
data: city})
.success( function(data, status, headers, config){
console.log($scope.city);
console.log(data);
console.log($scope.city);
}).
error(function(data,status,headers,config){
jQuery('.alert').show();
console.log('nope');
});
};
});
<form ng-controller="CityCreateController">
<legend> New City</legend>
<input for="City-group" name="City" id="City" type="text" ng-model="city.city" placeholder="City Name">
<input for="City-group" name="desc" id="desc" type="text" ng-model="city.desc" placeholder="Description">
<input type="submit" class="btn btn-default" ng-click="saveCity(city)"/>
</form>
<ul ng-controller="CityIndexController" class="city-list">
<li ng-repeat="city in cities">
<a href="#">
{{city.city}}</a></li>
</ul>
It should looks something like that
;(function() {
function Cities($http) {
function City() {
}
City.prototype.save = function() {
return $http.post('/api/city', this);
};
City.cities = [];
City.add = function(city) {
city.save().then(function() {
City.cities.push(city);
});
};
City.getAll = function() {
$http.get('/api/cities').then(function(response) {
City.cities = response.data.map(function(data) {
return new City(data);
});
return cities;
});
};
return City;
}
function CityCreateController(Cities) {
var mv = this;
mv.city = new Cities();
mv.saveCity = function() {
Cities.add(mv.city);
};
}
function CityIndexController($scope, Cities) {
var mv = this;
$scope.$watchCollection(function() {
return Cities.cities;
}, function(cities) {
mv.cities = cities || [];
});
Cities.getAll();
}
angular
.module('app', [])
.factory('Cities', ['$http', Cities])
.controller('CityCreateController', ['Cities', CityCreateController])
.controller('CityIndexController', ['$scope', 'Cities', CityIndexController]);
})();
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<meta charset="utf-8">
</head>
<body ng-app="app">
<form ng-controller="CityCreateController as mv">
<legend> New City</legend>
<input for="City-group" name="City" id="City" type="text" ng-model="mv.city.city" placeholder="City Name">
<input for="City-group" name="desc" id="desc" type="text" ng-model="mv.city.desc" placeholder="Description">
<input type="submit" class="btn btn-default" ng-click="mv.saveCity()"/>
</form>
<ul ng-controller="CityIndexController as mv" class="city-list">
<li ng-repeat="city in mv.cities">
<a href="#">
{{city.city}}</a></li>
</ul>
</body>
</html>
Found a simple fix
angular.module('Cityapp').controller('CityCreateController', function(City, $scope, $http){
$scope.cities = City.query();
$scope.city = new City();
$scope.saveCity = function(city){
$http({
method: 'POST',
url: '/city',
data: city})
.success( function(data, status, headers, config){
$scope.cities.push({city: $scope.city.city,
desc: $scope.city.desc});
}).
error(function(data,status,headers,config){
jQuery('.alert').show();
console.log('nope');
});
};
});
Just added the
$scope.cities.push({city: $scope.city.city,
desc: $scope.city.desc});
to the .success. Works like it should. Now on to my next issue.
i know its very common and very easy thing but really i m very new to angularjs and need your help
My View Page:
<div ng-controller="AddressController">
<div class="form-part-title" ng-show="Caption">{{Caption}} <span ng-show="showSameAsBilling" class="spancheck"><input type="checkbox" id="SameAsBilling" ng-model="Address.SameAsBilling"><label class=" after">Same As Billing Address</label></span> </div>
<div ng-show="!readOnly">
<label class="required">#Resource.Country<span ng-show="showInvalidAddress" class="spancheck"><input type="checkbox" id="InvalidAddress" ng-model="Address.InvalidAddress"><label class="after">Invalid Address</label></span>
<span ng-show="showPostalOnly" class="spancheck"><input type="checkbox" id="PostalOnly" ng-model="Address.PostalOnly"><label class="after">Postal Only</label></span>
</label>
<select kendo-drop-down-list class="sdk-dropdown" ng-model="Address.CountryId" k-options="countries" k-on-change="onChange(kendoEvent)" />
<label>#Resource.Address</label>
<input class="block" type="text" name="Address" ng-model="Address.Address1" maxlength="100" />
<input class="block" type="text" ng-model="Address.Address2" maxlength="100" />
<input class="block" type="text" ng-model="Address.Address3" maxlength="100" />
<label id="lblState">{{StateLabel}}</label>
<select kendo-drop-down-list class="sdk-dropdown" ng-model="Address.StateProvinceId" k-options="states" k-rebind="states" />
<label>#Resource.City</label>
<input class="block" type="text" name="City" ng-model="Address.City" maxlength="50" />
<label>{{ZipCodeLabel}}</label>
<input class="block" type="text" name="ZipCode" ng-model="Address.ZipCode" maxlength="50" />
</div>
<div ng-show="readOnly">
<textarea style="min-height:120px!important" disabled>{{Address.Address}}{{Address.Address1}}
{{Address.Address2}}
{{Address.City}}
{{Address.State}}{{Address.CountryName}}
{{Address.ZipCode}}</textarea>
</div>
</div>
My Angular Controller:
var AddressController = function ($scope, $http, $routeParams, $location) {
$scope.StateLabel = "State";
$scope.ZipCodeLabel = "Zip Code";
$scope.countryDataSource = {
transport: {
read: {
dataType: "json",
url: "/ApplicationData/GetCountries",
}
}
};
$scope.countries = {
dataSource: $scope.countryDataSource,
dataTextField: "Name",
dataValueField: "Id",
optionLabel: "Select..."
};
this.showAlert = function () {
alert("this is test method");
};
$scope.onChange = function (e) {
var countryId = e.sender.value();
if (countryId == 2) {
$scope.StateLabel = "Province";
$scope.ZipCodeLabel = "Postal Code";
}
else {
$scope.StateLabel = "State";
$scope.ZipCodeLabel = "Zip Code";
}
$http.get('/ApplicationData/GetStates/' + countryId).
success(function (jsonData, status, headers, config) {
console.log(jsonData);
var data = {
dataSource: jsonData,
dataTextField: "Name",
dataValueField: "Id",
optionLabel: "Select..."
};
$scope.states = data;
}).
error(function (data, status, headers, config) {
console.log("error getting countries");
});
};
$scope.SameAsBilling = function (checked) {
alert(1);
if (SameAsBilling.checked = true) {
vmCustomer.BillingAddress = vmCustomer.ShippingAddress
}
};
};
AddressController.$inject = ['$scope', '$http', '$routeParams', '$location'];
i need you guys to help me with the below function
$scope.SameAsBilling = function (checked) {
alert(1);
if (SameAsBilling.checked = true) {
vmCustomer.BillingAddress = vmCustomer.ShippingAddress
}
};
i m tying but don't know why the check box is not talking to controller please help
I should manage a directive for a login
form because of append a msg just in case
the credentials are wrong so I end up with:
HTML
<form role="form" name="form" data-auth="" data-ng-submit="getAuth()" class="form-signin">
<h2 class="form-signin-heading">Please sign in</h2>
<input type="text" name="email" placeholder="Email address" required="required" autofocus="autofocus" data-ng-model="user.email" class="form-control">
<input type="password" name="password" placeholder="Password" required="required" data-ng-model="user.password" class="form-control">
<label class="checkbox">
<input type="checkbox" value="remember-me">Remember me
</label>
<input type="submit" value="Sign in" data-ng-disabled="form.$invalid" class="btn btn-lg btn-primary btn-block">
</form>
JS
.factory('Auth', function($http,$q,$window) {
return {
send : function(data){
var deferred = $q.defer();
$http.post('/user/auth',data)
.success(function (response) {
deferred.resolve(response);
})
.error(function(data, status, headers, config) {
deferred.reject([]);
});
return deferred.promise;
},
authenticate:function(data){
}
}
})
.controller('MainCtrl', function ($scope,Auth) {
$scope.user = {};
})
.directive('auth',function($window,Auth) {
return {
restrict: 'A',
controller: function($scope,$element) {
$scope.getAuth = function(){
Auth.send($scope.user).then(
function(response){
if( (typeof response.data !== 'undefined') && (response.data === $scope.user.email)){
$window.location.href = 'http://localhost:3000/admin';
}
},
function(reject){
$('#invalid-login').remove();
$element.prepend('<p id="invalid-login" class="text-danger text-center">Invalid login</p>');
}
);
};
}
};
});
I'd like to put all the logic in the service
but I don't find the way ^^
EDIT
.factory('Auth', function($http,$q,$window) {
return {
send : function(data){
var deferred = $q.defer();
$http.post('/user/auth',data)
.success(function (response) {
deferred.resolve(response);
})
.error(function(data, status, headers, config) {
deferred.reject([]);
});
return deferred.promise;
},
authenticate:function(data,callBackOnError){
this.send(data).then(
function(response){
if( (typeof response.data !== 'undefined') && (response.data === data.email)){
$window.location.href = 'http://localhost:3000/admin';
}
},
callBackOnError
);
}
}
})
.controller('MainCtrl', function ($scope,Auth) {
$scope.user = {};
})
.directive('auth',function($window,Auth) {
return {
restrict: 'A',
controller: function($scope,$element) {
$scope.getAuth = function(){
Auth.authenticate(
$scope.user,
function(reject){
$('#invalid-login').remove();
$element.prepend('<p id="invalid-login" class="text-danger text-center">Invalid login</p>');
}
);
};
}
};
});
not so bad ^^
Change your HTML such that your call to getAuth has the user as parameter
<form role="form" name="form" data-auth="" data-ng-submit="getAuth(user)" class="form-signin">
<h2 class="form-signin-heading">Please sign in</h2>
<input type="text" name="email" placeholder="Email address" required="required" autofocus="autofocus" data-ng-model="user.email" class="form-control">
<input type="password" name="password" placeholder="Password" required="required" data-ng-model="user.password" class="form-control">
<label class="checkbox">
<input type="checkbox" value="remember-me">Remember me
</label>
<input type="submit" value="Sign in" data-ng-disabled="form.$invalid" class="btn btn-lg btn-primary btn-block">
Change your service such that it includes the getAuth function:
.factory('Auth', function($http,$q,$window) {
return {
send : function(data){
var deferred = $q.defer();
$http.post('/user/auth',data)
.success(function (response) {
deferred.resolve(response);
})
.error(function(data, status, headers, config) {
deferred.reject([]);
});
return deferred.promise;
},
authenticate:function(data){
},
getAuth: function(user){
send(user).then(
function(response){
if( (typeof response.data !== 'undefined') && (response.data === $scope.user.email)){
$window.location.href = 'http://localhost:3000/admin';
}
},
function(reject){
$('#invalid-login').remove();
$element.prepend('<p id="invalid-login" class="text-danger text-center">Invalid login</p>');
}
);
}
}
})
And finally change the controller like that:
.controller('MainCtrl', function ($scope,Auth) {
$scope.user = {};
$scope.getAuth = Auth.getAuth;
})