Building array in controller AngularJS - angularjs

So I have a client controller like so (with only relevant code):
angular.module('employees').controller('EmployeesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Employees',
function($scope, $stateParams, $location, Authentication, Employees) {
$scope.authentication = Authentication;
// Create new Employee
$scope.create = function() {
// Create new Employee object
var employee = new Employees ({
name: this.name,
eid: this.eid,
availibility: [monday: this.monday, tuesday: this.tuesday]
});
With a client view (again, only code relevant to the availability array)
<div class="form-group form-inline">
<label class="control-label" for="monday">Monday</label>
<label class="control-label" for="start">Start</label>
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input type="checkbox" id="monday" class="form-control" required>
<input type="time" id="start" class="form-control" required> <input type="time" id="finish" class="form-control" required>
</div>
</div>
<div class="form-group form-inline">
<label class="control-label" for="tuesday">Tuesday</label>
<label class="control-label" for="start">Start</label>
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input type="checkbox" id="tuesday" class="form-control" required>
<input type="time" id="start" class="form-control" required>
<input type="time" id="finish" class="form-control" required>
</div>
</div>
And a server controller like so:
exports.create = function(req, res) {
var employee = new Employee(req.body);
employee.user = req.user;
console.log(req.body);
employee.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(employee);
}
});
};
How can I make it so that the user can update an "availability" schedule? For some reason, when I POST the form, all I am getting is the eid and name (in the req.body). What am I doing wrong here? Can anyone point me in the direction of a resource that I could use?
Also, another question that kinda has something to do with this: Can I use ngTable to style these forms? As in, can I put forms inside of a table?
Thanks everybody for the help!
P.S. I realize the code is pretty dirty (particular the HTML code + the fact that none of my controllers are actually trying to pull data from the forms yet). Again, I don't have any real reason to continue on to that part until I know why when I POST the form, the data is not included in the post.

Things to try:
Verify spelling of availability you have availibility in your create function and it could be an issue with your setup.
It looks like you are probably using a mean.js-like setup. I would first confirm that you have added the availability field to your Employee object. In this case you would have to make the file app/model/employee.server.model.js (or where ever your model definition is to have the array)
_
new Employee({
name: {type: String},
eid: {type: String},
availibility: {type: Array,
default: []
}
}
Finally your create function looks a little funky to me. I would use a more standard definition for the array
// Create new Employee
$scope.create = function() {
// Create new Employee object
var employee = new Employees ({
name: this.name,
eid: this.eid,
availibility: [this.monday, this.tuesday]
});

Related

How to get data from form input

Im new to mobile development, especially using Ionic. Please help me out
I have this code for my route
.state('auth', {
url: '/auth',
templateUrl: 'templates/login.html',
controller: 'AuthCtrl'
I have this code for my login.html
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<div class="list list-inset">
<label class="item item-input">
<input type="text" placeholder="Mobile Number" ng-model="mobile_number">
</label>
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
and for my AuthCtrl
.controller('AuthCtrl', function($scope,$auth,$state) {
$scope.login = function() {
var credentials = {
mobile_number : $scope.mobile_number,
password : $scope.password,
}
console.log(credentials);
$auth.login(credentials).then(function(data) {
// If login is successful, redirect to the users state
$state.go('tab.dash', {});
});
}
})
I always get this Object {mobile_number: undefined, password: undefined} when calling console.log(credentials)
I always put values in my forms, but its always undefined. Why?
First initialize your scope credentials model:
$scope.credentials = {
'mobile_number' : ''
'password' : '',
}
Then bind your inputs to the scope properties:
<input type="text" placeholder="Mobile Number" ng-model="credentials.mobile_number">
<input type="password" placeholder="Password" ng-model="credentials.password">
And make use of $scope.credentials that now has your form data:
$auth.login($scope.credentials).then(function(data) {
// If login is successful, redirect to the users state
$state.go('tab.dash', {});
});
Your credentials object is not bound to scope. It looks like You need to declare $scope.credentials outside of login. Also on the input, ngModel should bind to credentials.password and credentials.mobile_number.
Actually it works good for me, I did a little plunker to test it. I was facing similar problem cause I added ng-pattern and ng-minLength directive in the input. In this case you will get undefined unless the input value is valid pattern and length. To fix it I added property to your input element
<input type="tel" ng-model="credentials.mobile_number"
ng-model-options="{allowInvalid:true}"/>
I hope that helps , good luck

AngularJS: Only post non-blank values

I am trying to $http.post a JSON object from a form. I can't seem to find the right syntax. Let's assume my form only takes one value (name). I use ng-model to bind the name to an object called modcampaign.name.
What's the correct syntax to post this to a http service?
Further, what if I had another input box, Description, and only want to bind this to modcampaign.description if the user entered data in the input box? If the input box is empty, I'd like to take the value for .description from another object (like modcampaign2.description).
<form ng-submit="modifyCampaign(selCampaign, newName)" class="form-horizontal" name="modCampaign">
<!-- Modify Name -->
<div class="form-group">
<label class="col-lg-2 control-label" for="modName">Name</label>
<div class="col-lg-8">
<input class="form-control" type="text" id="modName" ng-model="modCampaign.name"/>
</div>
</div>
</form>
This is the script file:
var myApp = angular.module('myApp', []);
myApp.controller('ListController', ['$scope', '$http', function($scope, $http) {
$http.get('js/campaigns.json').success(function (data) {
$scope.campaigns = data;
});
$http.post('js/campaign_mod.json').success(function (data) {
data = $scope.modCampaign;
});
$scope.selCampaign={};
$scope.selectCampaign = function (campaign) {
$scope.toggleCampaign = !$scope.toggleCampaign;
$scope.selCampaign = campaign;
};
$scope.abbrechen = function () {
$scope.toggleCampaign = !$scope.toggleCampaign;
};
$scope.submit = function () {
$http.post('')
}
}]);
You can include something like this in your controller:
$scope.modCampaign = {};
//this gets called on ng-submit
$scope.submitData = function(){
$http.post("api-end-point", $scope.modCompaign).success(function(data, status) {
//handle response etc.
});
}
Your html will have something like this:
<form ng-submit="submitData()" class="form-horizontal" name="modCampaign">
<!-- Modify Name -->
<div class="form-group">
<label class="col-lg-2 control-label" for="modName">Name</label>
<div class="col-lg-8">
<input class="form-control" type="text" id="modName" ng-model="modCampaign.name"/>
<textarea ng-model="modCampaign.description"/></textarea>
</div>
</div>
</form>
you can use JSON.stringify()
example
$http({
method: "POST",
url: 'http://www.example.com/posturl',
data : JSON.stringify($scope.modcampaign)
}).success(function(response){
console.log(response);
// write any action after post success
})
<form ng-submit="modifyCampaign(modCampaign)" class="form-horizontal" name="modCampaign">
<!-- Modify Name -->
<div class="form-group">
<label class="col-lg-2 control-label" for="modName">Name</label>
<div class="col-lg-8">
<input class="form-control" type="text" id="modName" ng-model="modCampaign.name"/>
</div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label" for="modDescription">Description</label>
<div class="col-lg-8">
<input class="form-control" type="text" id="modDescription" ng-model="modCampaign.description"/>
</div>
</div>
</form>
var myApp = angular.module('myApp', []);
myApp.controller('ListController', ['$scope', '$http', function($scope, $http) {
$scope.modifyCampaign = function(modCampaign) {
console.log(modCampaign)
alert(modCampaign.name) // name:"jane"
alert(modCampaign.description) // description: "hello"
$http.post('js/campaign_mod.json', { name: modCampaign.name, description: modCampaign.description }).success(function (data) {
console.log(data)
});
}
}]);
This method lets you bind all the form value to one object and then you can decode the value in your controller file, below is a link to a working example
http://codepen.io/anon/pen/VjYLvg

AngularJS error: TypeError: v2.login is not a function

I would like to call the login function when I click the login button but keep getting the error message in the title. Can someone point out the error in my script?
login.js code below:
/*global Firebase, angular, console*/
'use strict';
// Create a new app with the AngularFire module
var app = angular.module("runsheetApp");
app.controller("AuthCtrl", function ($scope, $firebaseAuth) {
var ref = new Firebase("https://xxxxx.firebaseio.com");
function login() {
ref.authWithPassword({
email : "xxxxx",
password : "xxxx"
}, function (error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
And the code for login.html is also below:
<div class="container" style="max-width: 300px">
<form class="form-signin">
<h2 class="form-signin-heading" style="text-align: center">Please Sign In</h2>
<input type="text" class="form-control" name="username" ng-model = "username" placeholder="Email Address" required="" autofocus="" />
</br>
<input type="password" class="form-control" name="password" ng-model = "password" placeholder="Password" required=""/>
</br>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-click="login()">Login</button>
</form>
</div>
Edge case here, but I want to mention it for posterities' sake. I got this same error when using the controllerAs pattern with a form name with the same value as ng-submit. For example:
<form name="authCtrl.signUp" ng-submit="authCtrl.signUp()">
Throws: TypeError: v2.signUp is not a function
The solution was to change the name of the form to something different:
<form name="authCtrl.signUpForm" ng-submit="authCtrl.signUp()">
In my case, I was having an exact same issue as yours. However, coming across gkalpak's answer to such a scenario helped me out.
Turned out to be what I was calling was addBuddy() function, from a form named "addBuddy". The solution was to change the name of either of the two things to make one stand out or differentiable from the other. I changed the name of the form to "addBuddyForm" and voila! My function worked!
Here's a snippet of my case:
<form name="addBuddy" class="form-horizontal" novalidate>
...
<button class="btn btn-sm btn-info" ng-click="addBuddy()>Submit</button>
Which, I changed to:
<form name="addBuddyForm" class="form-horizontal" novalidate>
...
<button class="btn btn-sm btn-info" ng-click="addBuddy()>Submit</button>
...and it worked! :)
In AngularJS call the function from view it must be in the $scope.
JS
// exposes login function in scope
$scope.login = login;
HTML
<div class="container" ng-controller="AuthCtrl" style="max-width: 300px"> <!-- I notice here for include ng-controller to your main div -->
<form class="form-signin">
<h2 class="form-signin-heading" style="text-align: center">Please Sign In</h2>
<input type="text" class="form-control" name="username" ng-model = "username" placeholder="Email Address" required="" autofocus="" />
</br>
<input type="password" class="form-control" name="password" ng-model = "password" placeholder="Password" required=""/>
</br>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-click="login()">Login</button>
</form>
This may not be specific to your problem, but I was also getting this error and it took a bit to figure out why.
I had named both a function and a variable the same, with the variable assigned in the function, and so the assignment of the variable was overriding the function and it was exploding on a second run.
You'll notice in the example the uploadFile() function as an upload.uploadFile = true; This was a wonderful file that was meant to be upload.uploadingFile - a flag used to control the behavior of a spinner. Once that was fixed, the issue went away.
Example:
(function()
{
'use strict';
angular.module('aumApp.file-upload')
.controller('FileUploadCtrl', FileUploadCtrl);
function FileUploadCtrl($scope, $http)
{
upload.uploadFile = function()
{
upload.uploadFile = true;
var backendUrl = '/ua_aumcore/events/api/v1/events/uploadFile';
var fd = new FormData();
fd.append('file', upload.src);
$http({ url: backendUrl, data: fd, method: 'POST', transformRequest : angular.identity, headers: { 'Content-Type' : undefined } })
.then(function uploadSuccess(response)
{
upload.data = response.data;
upload.message = "Uploaded Succesfully.";
upload.uploadSuccess = true;
upload.uploadingFile = false;
},
function uploadFailure(response)
{
upload.message = "Upload Failed.";
upload.uploadSuccess = false;
upload.uploadingFile = false;
});
};
}
FileUploadCtrl.$inject = ['$scope', '$http'];
})();
To be callable from the view, a function must be in the $scope. Add
$scope.login = login;
to the JS code of the controller.
You also need to actually use that controller. Change
<div class="container" style="max-width: 300px">
to
<div ng-controller="AuthCtrl" class="container" style="max-width: 300px">
This is all fundamental stuff. My advice would be to learn from an AngularJS tutorial before going further.
Two enable two-way binding you have to assign your login function to $scope. Replace your code for function with this:
$scope.login=function() {
ref.authWithPassword({
email : "nick.koulias#gmail.com",
password : "Jaeger01"
}, function (error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
}
It may be a late answer by me.
But It working for me
Check form name you set
e.g. ng-form="login"
and function name
e.g. ng-click="login()"
Then it will not work . You have to change one of them.
e.g. ng-form="loginForm"
Explanation:
AngularJS 1.x registers any form DOM element that has a name property in $scope via formDirectiveFactory. This directive automatically instantiates form.FormController if the above is true:
If the name attribute is specified, the form controller is published onto the current scope under
from: angular.js:24855
Hence if you have a <form name=myForm> it will override your $scope.myForm = function() { ... }

Adding hidden form field to array in Angular

I am trying to add a "hidden" field to a basic form in Angular (using Firebase as the backend). I'm having trouble figuring out how to include this field as part of the array when the form is submitted. I want to include {type: 'Basic'} as part of the array. I've looked at the other related posts on this site, but am still unsure how to apply to my particular situation.
Any suggestions on how to do this?
Javascript:
myApp.controller('NewProjectCtrl', function ($location, Projects) {
var editProject = this;
editProject.type = 'Basic'; //this is the hidden field
editProject.save = function () {
Projects.$add(editProject.project).then(function(data) {
$location.path('/');
});
};
});
HTML:
<form>
<div class="control-group form-group">
<label>Name</label>
<input type="text" name="name" ng-model="editProject.project.name">
</div>
<label>Description</label>
<textarea name="description" class="form-control" ng-model="editProject.project.description"></textarea>
<button ng-click="editProject.save()" class="btn btn-primary">Save</button>
</form>
You don't need a hidden form field, just submit your value in your controller like this:
editProject.save = function () {
editProject.project.type = 'Basic';
Projects.$add(editProject.project).then(function(data) {
$location.path('/');
});
};
All attributes of your editProject.project will be submitted, as you may notice in the developer console.
I would structure the controller a bit different.. here is an example (I am considering you are using angular-resource, where Projects returns a Resource?):
myApp.controller('NewProjectCtrl', function ($location, Projects) {
$scope.project = new Projects({type: 'Basic'});
$scope.save = function () {
$scope.project.$save().then(function(data) {
$location.path('/');
});
};
});
<form ng-submit="save()">
<div class="control-group form-group">
<label>Name</label>
<input type="text" name="name" ng-model="project.name">
</div>
<label>Description</label>
<textarea name="description" class="form-control" ng-model="project.description"></textarea>
<input type="submit" value="Save" class="btn btn-primary" />
</form>
The save function will $save the new project resource (this is an default method and will make a POST on the given resource URL).

How to dynamically change input value

I'm trying to show some editable results to the users, so I show them through an input field. This is a basic example of what I'm doing:
<div class="form-group">
<label>First number</label>
<input type="text" ng-model="first" ng-required="true" class="form-control">
</div>
<div class="form-group">
<label>Second number</label>
<input type="text" ng-model="second" ng-required="true" class="form-control">
</div>
<div class="form-group">
<label>The sum is: {{first + second }}</label>
<input type="text" ng-model="result" ng-required="true" class="form-control">
</div>
In the result's div, I used a label to test if the result is being obtained correctly, and it is. But if I edit the first or second values, the input's result doesn't update.
This is the controller used (yeah, the form is in a modal):
var ModalInstanceCtrl = function ($scope, $modalInstance) {
$scope.result = $scope.first + $scope.second;
$scope.confirm = function () {
$modalInstance.close(result);
};
$scope.cancelNewBet = function () {
$modalInstance.dismiss('cancel');
};
};
I thought the value was supposed to get automatically updated once I define how it is obtained. But clearly it misses something to change the result through script...
Thanks in advance.
What do you want to happen when the user edits the results input? Do you want the data binding to break (I assume not and ignore this possibility)? Do you want one of the inputs to adjust to the proper value?
If you only want to display the output, do this, in your controller:
$scope.result = function() { return $scope.first + $scope.second; }
And in your view:
{{ result() }}
But if you want the user to be able to edit the result and (let's say) have second be assigned (result - first), then you'd want something like this in your view (by the way, note the type="number"):
<input type="number" ng-change="adjustResult()" ng-model="first">
<input type="number" ng-change="adjustResult()" ng-model="second">
<input type="number" ng-change="adjustInput()" ng-model="result">
And in your controller:
$scope.adjustResult = function() {
$scope.result = $scope.first + $scope.second;
};
$scope.adjustResult(); // initialize result
$scope.adjustInput = function() {
$scope.second = $scope.result - $scope.first;
}

Resources