Connect Express nodemailer with Angular - angularjs

I'm trying to make a contact form, and the server side is working pretty well. But I don't know how to connect Angular to the html form and send it with Express. Any would appreciate any help.
My Express
router.get('/sendQuote', function(req, res) {
var data = req.query;
var mailOptions = {
from: 'planacte#gmail.com', // sender address
name: data.contactName,
email: data.contactEmail,
to: data.email, // list of receivers
subject: "Request for a Quote from " + data.contactName, // Subject line
text: data.contactMsg, // plaintext body
html: '<p> email: ' + data.contactEmail +
'</p><p> phone: ' + data.contactPhone + '</p><br>'
+data.contactMsg // html body
};
console.log(mailOptions)
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
});
So, my html:
<form id="contact" class="contact-form" ng-submit="sendMail()" novalidate>
<div class="message"></div>
<div class="col-md-5 col-sm-5 col-xs-12 animated hiding" data-animation="slideInLeft">
<div class="form-group">
<input type="text" name="name" class="nameform form-control input-lg" placeholder="name" ng-model="contactName" required>
</div>
<div class="form-group">
<input type="email" name="email" class="emailform form-control input-lg" placeholder="email" ng-model="message.contactEmail" required>
</div>
<div class="form-group">
<input type="text" name="phone" class="phoneform form-control input-lg" placeholder="phone" ng-model="message.contactPhone">
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<div class="form-group">
<textarea name="message" class="messageform form-control input-lg" placeholder="custom text" ng-model="message.contactMsg" required></textarea>
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<input type="submit" class="btn btn-custom up form-button" value="Send Message">
And the main problem is here, how to glue Angular with HTML and Express. I can send emails, but get undefined in the fields of Name, Email and so on. :
app.controller('MainCtrl', ['$scope', '$interval', '$http', '$location', '$anchorScroll',
function($scope, $interval, $http, $location, $anchorScroll) {
$scope.sendMail = function () {
$scope.message = {};
$http.get('/send/sendQuote', $scope.message).
success(function(data, status, headers, config) {
// $scope.message = data.message;
console.log($scope.message)
});
}
}]);

I think you should start by making this request a POST and not a GET request.
router.post('/sendQuote', function(req, res) {
var data = req.body;
var mailOptions = {
from: 'planacte#gmail.com', // sender address
name: data.contactName,
email: data.contactEmail,
to: data.email, // list of receivers
subject: "Request for a Quote from " + data.contactName, // Subject line
text: data.contactMsg, // plaintext body
html: '<p> email: ' + data.contactEmail +
'</p><p> phone: ' + data.contactPhone + '</p><br>'
+data.contactMsg // html body
};
console.log(mailOptions)
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
res.send(200); // let the client know it sent ok.
});
Now, let's take a look at your Angular code. It seems you want the object $scope.message to hold your form fields data. You should define this as an object at the beginning of your controller.
app.controller('MainCtrl', ['$scope', '$interval', '$http', '$location', '$anchorScroll',
function($scope, $interval, $http, $location, $anchorScroll) {
$scope.message = {};
$scope.sendMail = function () {
//$scope.message = {}; -- this was clearing the object
$http.post('/send/sendQuote', $scope.message).
success(function(data, status, headers, config) {
// you can clear $scope.message if you want here
// $scope.message = data.message;
console.log($scope.message)
});
}
}]);
HTML had one ng-model not binding to the message object:
<form id="contact" class="contact-form" ng-submit="sendMail()" novalidate>
<div class="message"></div>
<div class="col-md-5 col-sm-5 col-xs-12 animated hiding" data-animation="slideInLeft">
<div class="form-group">
<input type="text" name="name" class="nameform form-control input-lg" placeholder="name" ng-model="message.contactName" required>
</div>
<div class="form-group">
<input type="email" name="email" class="emailform form-control input-lg" placeholder="email" ng-model="message.contactEmail" required>
</div>
<div class="form-group">
<input type="text" name="phone" class="phoneform form-control input-lg" placeholder="phone" ng-model="message.contactPhone">
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<div class="form-group">
<textarea name="message" class="messageform form-control input-lg" placeholder="custom text" ng-model="message.contactMsg" required></textarea>
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<input type="submit" class="btn btn-custom up form-button" value="Send Message">

Related

setPristine is not a function

I got my angular form all setup and working. The values are set after calling a response to a json request. The form is succesfully populated with the json response. After that i want to 'reset' the form, as in $scope.object.$setPristine. But i get an error:
$scope.object.$setPristine is not a function
I'm using angular 1.4.8.
Here is my HTML:
<div ng-app="myApp" ng-controller="formController" class="ng-scope">
<form name="object" ng-submit="submit()" method="post" action="" novalidate="" class="ng-pristine ng-valid">
<div class="form-group">
<label class="control-label" for="object_name">Name</label>
<input type="text" id="object_name" name="object[name]" ng-model="object.name" class="form-control ng-pristine ng-valid ng-touched" value="Object 2c">
</div>
<div class="form-group">
<label class="control-label" for="object_elements">Elements</label>
<select id="object_elements" name="object[elements][]" ng-model="object.elements" ng-options="opt.id as opt.name for opt in options | orderBy: "id"" class="form-control ng-pristine ng-untouched ng-valid" multiple="multiple"></select></div>
<div class="form-group">
<input ng-disabled="object.$pristine" class="btn btn-primary" value="Save" ng-click="submitForm()">
</div>
</form>
</div>
And here is my .js:
var app = angular.module('myApp', ["ngResource"]).controller('formController', function ($scope, $http, $location) {
var url = $location.absUrl() + '/json'
$http({
method: 'GET',
url: url
}).then(function (response) {
$scope.status = response.status;
$scope.data = response.data;
$scope.object = response.data;
$scope.object.$setPristine();
$('#modal-loading').modal('hide');
}, function (response) {
$scope.data = response.data || "Request failed";
$scope.status = response.status;
$('#modal-loading').modal('hide');
});
});
You overwrite $scope.object with a JSON response, of course it doesn't have any functions attached to it.
$scope.object = response.data;
$scope.object.$setPristine();
This is functionally the same as:
$scope.object = {of_course: "this doesn't work"};
$scope.object.$setPristine();
You probably just need to change your ng-models to reference $scope.data instead of $scope.object
ng-model="data.name"
and then not overwrite your form object.
My way is this...
<form name="newClntForm" id="newClnt" class="add(newClnt, newClntForm)">
<input type="text" class="form-control" ng-model="newClnt.name" placeholder="Contact Person Name" required >
</form>
And Controller Save Function is
function(newClnt, newClntForm){
angular.copy({},newClnt);
// newClntForm is form name
newClntForm.$setPristine();
newClntForm.$setUntouched();
};

Reset form on submit

I am submitting a form and then making all the field empty but it's not working. Form is getting submitted successfully but the fields are not getting reset. I am using angular-material for styling. Updated controller.
Html
<form name="myform">
<md-input-container>
<label for="name">Contact Name</label>
<input type="text" md-maxlength="20" required="" md-no-asterisk name="name" ng-model="info.name" md-autofoucs>
<div ng-messages="myform.name.$error" role="alert">
<div ng-message="required">This is required.</div>
<div ng-message="md-maxlength">The name has to be less than 20 characters long.</div>
</div>
</md-input-container>
<md-input-container>
<label for="phone">Phone Number</label>
<input type="text" name="phone" required md-no-asterisk ng-model="info.phone">
<div ng-messages="myform.phone.$error">
<div ng-message="required">This is required.</div>
</div>
</md-input-container>
<md-input-container>
<label for="email">Email</label>
<input type="text" name="email" ng-model="info.email">
</md-input-container>
<md-input-container>
<md-button class="md-primary" ng-click="saveit(info)">Save</md-button>
<md-button class="md-primary">Cancel</md-button>
</md-input-container>
</form>
**Function in Controller**
angular.module('contact', ['ui.router', 'ngMaterial', 'templates','ngMessages'])
.config(['$mdThemingProvider', '$stateProvider', function ($mdThemingProvider, $stateProvider) {
$mdThemingProvider.theme('default')
.primaryPalette('blue')
.accentPalette('orange');
$stateProvider
.state('home', {
url: '',
templateUrl: 'templates/home.html',
controller: 'MainCtrl as vm'
});
}]).controller('MainCtrl', function ($scope, $mdSidenav,$mdDialog,$mdToast, contacts) {
var vm = this;
$scope.searchText ="";
$scope.toggleSidenav = function(){
$mdSidenav('left').open();
};
contacts.getall().then(function(response){
console.log(response.data);
$scope.people = response.data;
});
$scope.saveit = function(detail, myform){
if (!detail.name || !detail.phone) { return ;}
contacts.add({
name: detail.name,
phone: detail.phone,
email: detail.email
});
$mdToast.show(
$mdToast.simple()
.content("ContactAdded!")
.position('top, right')
.hideDelay(2000)
);
$scope.people.push(detail);
$scope.info = {};
$scope.myform.$setPristine();
$scope.myform.$setUntouched();
};
$scope.showConfirm = function(ev, person) {
var confirm = $mdDialog.confirm()
.title('Are you sure?')
.ariaLabel('Lucky day')
.targetEvent(ev)
.ok('Please delete it!')
.cancel('I want to keep it.');
$mdDialog.show(confirm).then(function() {
contacts.deletethis(person.id).then(function(){
$mdToast.show(
$mdToast.simple()
.content("Deleted!")
.position('top, right')
.hideDelay(2000)
);
});
var index = $scope.people.indexOf(person);
$scope.people.splice(index,1);
}, function() {
$scope.status = 'You decided to keep your debt.';
});
}; });
<form name="myform">
<input type="text" ng-model="info.name">
<input type="text" ng-model="info.phone">
<input type="text" ng-model="info.email">
</form>
app.controller('MainCtrl', function($scope) {
$scope.info = {}; // name, phone, email
$scope.saveit = function() {
$scope.info.name = ''; // reset name
$scope.info.phone= ''; // reset phone
$scope.info.email= ''; // reset email
// reset form and disable error messages
$scope.myform.$setPristine();
$scope.myform.$setUntouched();
};
});
You are not using $scope and this for controller correctly. You can use $scope or controller as syntax to bind your scope with view.
I suggest you to read more about it here.
Update your saveit() function inside controller as below:
app.controller('MainCtrl', function($scope, $mdSidenav, $mdDialog, $mdToast) {
var vm = this;
vm.info = {};
//your rest the code
vm.saveit = function() {
//do your operations here
vm.info = {};
};
});
Update your html page as below:
<div ng-controller="MainCtrl as vm">
<form name="myform">
<md-input-container>
<label for="name">Contact Name</label>
<input type="text" ng-maxlength="20" required md-no-asterisk name="name" ng-model="vm.info.name" md-autofoucs>
</md-input-container>
<md-input-container>
<label for="phone">Phone Number</label>
<input type="text" name="phone" required md-no-asterisk ng-model="vm.info.phone">
</md-input-container>
<md-input-container>
<label for="email">Email</label>
<input type="text" name="email" ng-model="vm.info.email">
</md-input-container>
<md-input-container>
<md-button class="md-primary" ng-click="vm.saveit()">Save</md-button>
<md-button class="md-primary">Cancel</md-button>
</md-input-container>
</form>
</div>
Give $setPristine to reset the form after saving.
$scope.myform.$setPristine();
Another approach
app.controller('MainCtrl', function($scope, $mdSidenav, $mdDialog, $mdToast) {
var vm = this;
vm.info = {};
vm.saveit = function($event)
{
var form = angular.element($event.target).parent("form")[0];
if (form !== undefined) form.reset();
};
});
<div ng-controller="MainCtrl as vm">
<form name="myform">
<md-input-container>
<label for="name">Contact Name</label>
<input type="text" ng-maxlength="20" required md-no-asterisk name="name" ng-model="vm.info.name" md-autofoucs>
</md-input-container>
<md-input-container>
<label for="phone">Phone Number</label>
<input type="text" name="phone" required md-no-asterisk ng-model="vm.info.phone">
</md-input-container>
<md-input-container>
<label for="email">Email</label>
<input type="text" name="email" ng-model="vm.info.email">
</md-input-container>
<md-input-container>
<md-button class="md-primary" ng-click="vm.saveit($event)">Save</md-button>
<md-button class="md-primary">Cancel</md-button>
</md-input-container>
</form>
</div>
The answer below is missing one line of code to work properly
You can check the answer from another question right here:
https://stackoverflow.com/a/40267630/4767208

User login with Angularjs and Firebase

I am trying to find a way to create a simple login form with Angularjs and Firebase. I currently have a simple signup form, which adds a userName into my firebase database. All I need to know is how to get a login page that accepts a user once the userName is identified in the firebase system, and to possibly make a callback error if there is no such userName within the database. This is my signup form:
<html ng-app="myApp">
<body ng-controller="userCtrl">
<div class="centerForm">
<form>
<div class="form-group">
<label for="exampleInputUser">Username</label>
<input type="username" ng-model="userName" class="form-control" id="exampleInputUser" placeholder="username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" ng-model="userPassword" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<table class="nav" align="center">
<tr>
<td>
<p><button type="submit" class="btn btn-primary" ng-click="saveUser()">Submit</button>
Sign Up</p>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
and this is my sign up code:
<script>
angular.module('myApp', [])
.controller('userCtrl', function($scope) {
$scope.userName ="";
$scope.userPassword="";
$scope.myData = new Firebase( "https://myfirebaseapp.firebaseio.com/")
$scope.saveUser = function() {
$scope.myData.push({userName: $scope.userName});
};
});
</script>
My login form would then look something like:
<html ng-app="myApp">
<body ng-controller="userCtrl">
<div class="centerForm">
<form>
<div class="form-group">
<label for="exampleInputUser1">Username</label>
<input type="username" ng-model="userName" class="form-control" id="exampleInputUser1" placeholder="username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" ng-model="userPassword" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<table class="nav" align="center">
<tr>
<td>
<p><button type="submit" class="btn btn-primary" ng-click="loginUser()">Submit</button>
Sign Up</p>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
AngularFire exists for this reason- to bind Angular with Firebase.
Here's a working example. This is the login controller:
var app = angular.module('appName');
app.factory("Auth", ["$firebaseAuth",
function($firebaseAuth) {
var ref = new Firebase("https://yourtester.firebaseio.com");
return $firebaseAuth(ref);
}
]);
app.controller('loginCtrl', ['$scope', '$state', '$http', 'Auth',
function($scope, $state, $http, Auth) {
$scope.auth = Auth;
$scope.auth.$onAuth(function(authData) {
$scope.authData = authData;
});
$scope.login = function() {
Auth.$authWithPassword({
email: $scope.email,
password: $scope.password
})
.then(function(authData) {
console.log('Logged in as:', authData.uid);
//$state.go('profile');
})
.catch(function(err) {
console.log('error:',err);
//$state.go('login');
});
};
}
]);
And this is the login.html file:
<body ng-app='appName' ng-controller="loginCtrl">
<h1>Login!</h1>
<form ng-submit='login()'>
<div class="form-group">
<label for="email">Email address</label>
<input id="email" ng-model='email' type="email" placeholder="Email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input id="password" ng-model='password' type="password" placeholder="Password" required>
</div>
<button class="btn btn-success">Login</button>
</form>
I'm using angular JS and my login function for Firebase looks like this in the controller:
app.factory("Auth", ["$firebaseAuth",function($firebaseAuth) {
var ref = new Firebase("https://myfirebaseapp.firebaseio.com");
return $firebaseAuth(ref);
}]);
$scope.login = function() {
$scope.authObj.$authWithPassword({
name: $scope.data.name,
email: $scope.data.email,
password: $scope.data.password
}).then(function(authData) {
authenticated = true;
console.log("Logged in as:", authData.uid, authenticated);
$location.path("profile");
check();
}).catch(function(error) {
authenticated = false;
console.error("Authentication failed:", error);
check();
});
}

angularjs form post http interceptor not working

i am new to angularjs so pardon my ignorance. Here is the interceptor i have for my angularjs app
.config(function ($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
$httpProvider.interceptors.push('authInterceptor');
})
.factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
return {
// Add authorization token to headers
request: function (config) {
config.headers = config.headers || {};
if ($cookieStore.get('token')) {
config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
}
return config;
},
// Intercept 401s and redirect you to login
responseError: function(response) {
if(response.status === 401) {
$location.path('/login');
// remove any stale tokens
$cookieStore.remove('token');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
};
})
I have an html which posts the data to the server
<form role="form" id="addTeacherForm" data-validate="parsley" action="/api/v1/teacher" method="post">
<h4>Add your Teacher's data</h4>
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-5 col-md-5">
<input type="text" ng-model="teacher.name" name="name" class="form-control input-md"
placeholder="Name" required="required">
</div>
<div class="col-xs-12 col-sm-5 col-md-5">
<input type="date" ng-model="teacher.dob" name="dob" class="form-control input-md"
placeholder="Date Of Birth" required="required">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-5 col-md-5">
<div class="input-icon"><i class="icon-user"></i>
Teacher's Photo
<input type="file" id="teacherPhoto" name="teacherPhoto" accept="image/*" required="required">
</div>
</div>
<div class="col-xs-12 col-sm-5 col-md-5">
<div class="form-group">
<input type="text" name="phoneNumber" ng-model="teacher.phoneNumber"
class="form-control input-md" name="phoneNumber"
placeholder="Phone Number(Optional)">
</div>
</div>
</div>
</div>
<div class="form-actions text-center">
<div class="col-xs-12 col-sm-5 col-md-5">
<input type="submit" value="Submit" class="btn btn-primary btn-block btn-md">
</div>
</div>
</form>
Now when i press submit on this form the request goes to the server but the interceptor doesn't get invoked and the request fails because the headers are not populated with the authorization token. Any idea why this is not being intercepted?

How to $http.post with payload in data?

How do I post data from a form in AngularJS?
<form data-ng-submit="doSomething()">
<input type="text" data-ng-input="do_obj.text"/>
<input type="email" data-ng-input="do_obj.email"/>
<input type="submit" value="Do something"/>
</form>
$scope.doSomething = function () {
$http({url: '/api/oauth2/register', method: 'POST', data: $scope.do_obj}
).then(function (data, status, headers, config) {
$log.info("data = ", data, "status = ", status,
"headers = ", headers, "config = ", config);
}
);
};
Plnkr (bootstrap styled)
See plunker code here
Changed data-ng-input into data-ng-model and updated data-ng-submit to pass in the model into the scope controller for processing.
HTML:
<body data-ng-app>
<div data-ng-controller="DoCtrl" class="container" style="margin: 15px">
<form data-ng-submit="doSomething(do_obj)" role="form" class="form-inline">
<div class="form-group">
<input type="text" data-ng-model="do_obj.bar"
placeholder="Enter text"
/>
</div>
<div class="form-group">
<input class="form-group" type="email"
data-ng-model="do_obj.email"
placeholder="Enter email"
/>
</div>
<div class="form-group">
<input class="btn btn-lg" type="submit"
data-ng-class="{'btn-info': hover}"
data-ng-mouseenter="hover = true"
data-ng-mouseleave="hover = false"
value="Do something"
/>
</div>
</form>
</div>
</body>
The syntax for posting is $http.post({url}, {payload});. I have updated your controller function to take in a parameter to pass to the post.
Controller code:
function DoCtrl($scope, $http, $log) {
$log.info("In DoCtrl");
$scope.do_obj = {};
$scope.doSomething = function (data) {
$http.post('/api/oauth2/register', data)
.success(function(successData){
console.log(successData);
});
}
}

Resources