Fill a text input from the scope in angularjs - angularjs

I have a text input in a form that I want to fill with data I'm getting from a promise.
this is my text input :
<input type="text" name="lastname" id="lastname" class="form-control input-lg"
ng-model="candidature.lastname"
required>
And In my controller I have this :
candidatureService.get({id: $rootScope.username}).$promise.then(function (res) {
$scope.candidature = {};
$scope.candidature.lastname = res.nom;
//code...
}).catch(function (err) {
console.log('Error getting data');
});
When I inspected my application using batrang I can see that the object candidature in $scope has the value I'm getting using that promise :
And as you can see I have ng-model="candidature.lastname".
Does anyone know why the text input doesn't get the value from the scope?
Thanks in advance.

Try declaring $scope.candidature = {}; before you make the API request...
But from the code it looks like you have only declared $scope.candidature.lastname and not $scope.candidature.firstname.

Related

Angular 1 dynamic form object

I'm using Angular 1 and creating a dynamic form. It works by looping through some objects and rendering dynamically binded input fields like:
<div class="quest-form form-group" ng-repeat="task in tasks">
<div ng-if="task.Class == 'TaskText'" ng-class="'task ' + task.Class">
<input ng-model="questForm.Task[task.ID].Value" ng-name="task_{{task.ID}}" ng-required="task.Required == 1" type="text" class="form-control" placeholder="{{task.Title}}" />
</div>
...
...
</div>
I also have a upload field in the loop:
<div ng-if="task.Class == 'TaskUpload'" ng-class="'task ' + task.Class">
<input class="btn btn-primary upload-btn" ngf-max-size="10MB" type="file" ng-model="upload" ngf-multiple="false" ngf-select="uploadFile(upload, task.ID, $invalidFiles)" />
<input class="" ng-model="questForm.Task[task.ID].FileUploadID" ng-required="task.Required == 1" ng-name="task_{{task.ID}}" type="text" />
</div>
When the file uploaded event is called I'm trying to set the value of the hidden field which is ng-model="questForm.Task[task.ID].FileUploadID" like this:
$scope.uploadFile = function(file,taskID) {
file.upload = Upload.upload({
url: assetsURL+'/home/UploadFile',
data: {file: file}
});
file.upload.then(function (response) {
$scope.questForm.Task[taskID].FileUploadID = response.data; // THIS MESSES UP
}, function (response) {
...
});
};
I get the following error, it's like $scope.questForm.Task[128] does not exist even though the hidden input looks correct and is binded to the $scope.questForm.Task[128].
angular.js:14362 TypeError: Cannot read property '128' of undefined
at file.upload.then.$scope.errorMsg (http://localhost/carl-mygps-app/js/controllers/quest-details-controller.js:120:26)
at processQueue (http://localhost/carl-mygps-app/bower_components/angular/angular.js:16689:37)
at http://localhost/carl-mygps-app/bower_components/angular/angular.js:16733:27
at Scope.$eval (http://localhost/carl-mygps-app/bower_components/angular/angular.js:18017:28)
at Scope.$digest (http://localhost/carl-mygps-app/bower_components/angular/angular.js:17827:31)
at Scope.$apply (http://localhost/carl-mygps-app/bower_components/angular/angular.js:18125:24)
at done (http://localhost/carl-mygps-app/bower_components/angular/angular.js:12233:47)
at completeRequest (http://localhost/carl-mygps-app/bower_components/angular/angular.js:12459:7)
at XMLHttpRequest.requestLoaded (http://localhost/carl-mygps-app/bower_components/angular/angular.js:12387:9) Possibly unhandled rejection: {}
I have tried defining blank objects in the scope like:
$scope.questForm = [];
$scope.questForm.Task = {};
But I should not need to because they are created in the template? confused. Thanks all.
Actually nope. Having your template compiled does not mean all the ng-models are initialized. While ng-model is smart enough to create all the intermediate objects, if they don't exist, it doesn't do so until $viewValue is changed. In your case if you upload a file without editing any other input first, $viewValue for inputs has never changed, and thus you have to initialize questForm, questForm.Task, and questForm.Task[taksID] yourself.
if (!$scope.questForm) {
$scope.questForm = {};
}
if (!$scope.questForm.Task) {
$scope.questForm.Task = {};
}
if (!$scope.questForm.Task[taskID]) {
$scope.questForm.Task[taskID] = {};
}
$scope.questForm.Task[taskID].FileUploadID = response.data;
Or you can initialize questForm and questForm.Task at the beginning. And only check if questForm.Task[taskID] exists before initializing it.

How to empty form inputs in angular js after submission

Hello amazing Stackoverflow Coders, Please how do I empty form inputs in angular Js after form submission.
below is my working code
$rootScope.sendNow = function () {
if ($rootScope.send_login.username.length < 1)
alert("Please enter username");
else if ($rootScope.send_login.password.length < 1)
alert("Please enter password");
else {
$http.post($rootScope.server_url + "post_Data", $rootScope.send_login)
.success(function (response)
{
// on success
$('#send_login.username').val('');
$('#send_login.password').val('');
toastr.success('Successful');
}
).error(function (response)
{
alert("sending failed");
});
}
};
My Form is here below
<input type="text" id="username" name="username" ng-value="send_login.username">
<input type="text" id="pass" name="pass" ng-value="send_login.password">
<input type="button" ng-click="sendNow()" value="Send">
Unlike Ajax, I have tried this below but cannot get it to work
$('#send_login.username').val('');
$('#send_login.password').val('');
you should use ng-model in the input tag, like:
html:
<input type="text" ng-model="name">
<button ng-click="sendData()"> Send</button>
js (angularjs Controller):
$scope.sendData = function (item) {
$scope.name = "";
}
Its better to take every form field ng-modal as a property of a object, like you have taken in "send_login".
After form submission reinitialize this object send_login = {};
Every field will be reinitialize. and a undefined property doesn't create a error in angular.
You should avoid so much use of $rootScope in your code.
You need to change ng-value to ng-model (to bind the angular variable to html input) and on ajax success clear the binded variable:
$http.post('...').success(function (response) {
$rootScope.send_login = {};
});

how to show validation messages when form is submitted in angular js

I have form in which there are couple of text fields and an email field.
I want to validate all fields for required / mandatory validation. I want to validate email field for email format validation. I want to carry out validation only when I click on two buttons and show the validation messages at top of the page. I know that I can check for email and required validations on field and using ng-show and a flag I can show messages. However I want to check each field's value in a directive and then set the flag to true which will make the message appear.
Here is my HTML. this gets loaded why state provider in main page which also defines following template and a controller for it. so its just a view partial:
<form name="myForm">
<div ng-show="validationFailed">
<!-- here i want to display validation messages using cca.validationMsgs object -->
</div>
<input type="text" name="test" ng-model="cca.field1" require />
....
<input type="email" mg-model="cca.field2" />
<input type="button" name="mybutton" />
</form>
Now the controller defined in another JS file:
'use strict';
(function(){
angular.module('store', []);
app.controller("StoreController",function(){
var cca = this;
cca.validationMsgs = {};
cca.validationFailed = false; //this flag should decide whether validation messages should be displayed on html page or not.when its true they are shown.
...//other mapped fields
});
And here is unfinished directive which I want to define and write my logic. Logic will be something like this :
1) iterate all elements which have require set on them and check their
$validators object / $error.required object is set
2) if yes set validationFailed flag to true,add the validation message to validationMsgs object and break the loop.
3) check if email type field has $error.email object set and if yes
similarly set validationFailed flag to true and add corresponding message to the object. Not sure if I really need a directive for this. I would like to apply the directive inside a element.
app.directive("requireOnSubmit",function(){
var directiveDefinitionObject = {
restrict:'E',
//.... need to fill in
//I can use link funcion but not sure how to map
// validationMsgs and validationFailed objects in here.
};
return directiveDefinitionObject;
});
Without any code or use case to go after I'll just show you a generic way of validating input. I'm going to use a signup functionality as an example.
Create a service/factory which will carry out the validation and return a promise, if the validation fails it will reject the promise. If not, it will resolve it.
Important note: A promise can only be resolved once (to either be fulfilled or rejected), meaning that the first declaration of a resolve or reject will always "win", which means you can't override any resolve or reject. So in this example if a field is empty and a user's email is undefined, the error message will be All fields must be filled in and not Invalid email format.
auth.factory('validation', ['$q', function($q) {
return {
validateSignup: function(newUser) {
var q = $q.defer();
for (var info in newUser) {
if (newUser[info] === '') {
q.reject('All fields must be filled in');
}
}
if (newUser.email === undefined) {
q.reject('Invalid email format');
}
else if (newUser.password.length < 8) {
q.reject('The password is too short');
}
else if (newUser.password != newUser.confirmedPass) {
q.reject('The passwords do not match');
}
q.resolve(true);
return q.promise;
}
}
}]);
And then inject this into your controller
auth.controller('AuthCtrl', ['$scope', '$location', 'validation', function($scope, $location, validation) {
$scope.status = {
message: ''
}
// Make sure nothing is undefined or validation will throw error
$scope.newUser = {
email: '',
password: '',
confirmedPass: ''
}
$scope.register = function() {
// Validation message will be set to status.message
// This will also clear the message for each request
$scope.status = {
message: ''
}
validation.validateSignup($scope.newUser)
.catch(function(err) {
// The validation didn't go through,
// display the error to the user
$scope.status.message = err;
})
.then(function(status) {
// If validation goes through
if (status === true) {
// Do something
}
});
}
And in the HTML you can have something like this:
<form>
<div>
<label for="email">Email:</label>
<input type="email" id="email" ng-model="newUser.email">
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="confirm-pass" ng-model="newUser.password">
</div>
<div>
<label for="confirm-pass">Confirm password:</label>
<input type="password" id="confirm-pass" ng-model="newUser.confirmedPass">
</div>
<div>
<div>
<span ng-bind="status.message"></span>
</div>
</div>
<div>
<button ng-click="register(newUser)">Register</button>
</div>
</form>
You can use this example and modify it for your use case.

Angularjs ng-if not working with ng-model

I am using angularjs to integrate my api.
I am facing problem with using ng-if inside textbox.
so below is my snippet of HTML code:
<input type="text" value="" data-ng-if="edit" ng-model="name">
<input type="text" value="" data-ng-if="!edit" ng-model="singleAppDetails.name">
Here edit variable is there in scope
that is in my controller i have declared it like this:
$scope.edit = false;
So if edit is false it should get bind with ng-model="name"
and if edit is true it should get bind with ng-model="singleAppDetails.name"
But it is not binding it as expected.
Further I am using $http.post to post the data to server like below:
$scope.addApp = function(){
$scope.apps = [];
$scope.apps.push({'name':$scope.name, 'domain':$scope.domain, 'appId':$scope.appId, 'secret':$scope.secret});
// Writing it to the server
//
var dataObj = {
name : $scope.name,
domain : $scope.domain,
appId : $scope.appId,
secret : $scope.secret
};
var res = $http.post('http://192.168.1.30:8090/apps/', dataObj);
res.success(function(data, status, headers, config) {
$scope.message = data;
});
res.error(function(data, status, headers, config) {
alert( "failure message: " + JSON.stringify({data: data}));
});
// Making the fields empty
//
$scope.name='';
$scope.domain='';
$scope.appId = '';
$scope.secret = '';
};
But this always sends null data.
ng-if has its own scope. So the name attribute that is populated by the first input is in the ng-if scope instead of being in your controller scope.
The second input should work fine, provided that your controller initializes singleAppDetails to a non-null object:
$scope.singleAppDetails = {};
Rule of thumb: always have a dot in your ng-model. Always populate objects in the scope rather than the scope itself.
ng-if is creating a child scope because that the input elements does not see the scope variable defined in the controller you have two ways to solve this problem
use an object reference
ex :
$scope.user = { name : "" }
inside the template
<input type="text" ng-model='user.name' />
you can tell angular to look for the variable in parent scope instead child scope
<input type="text" ng-model='$parent.name' />

Firebase: Error: Key content was undefined. Cannot pass undefined in JSON. Use null instead."

Trying firebase for the first time. Got the whole thing working in a plunkr here:
http://plnkr.co/3WIrBn
var app = angular.module('myApp',['firebase']);
app.factory('chatMessages',["$firebaseArray",function($firebaseArray){
var ref = new Firebase('https://scanapp.firebaseIO.com/tut');
return $firebaseArray(ref);
}]);
app.controller('MyController'['$scope','chatMessages',function($scope,chatMessages){
$scope.test = 'hello world';
$scope.user = "anonymouse";
$scope.messages = chatMessages;
$scope.addMessage = function(){
$scope.messages.$add({
from: $scope.user,
content: $scope.message
});
$scope.message = '';
};
}]);
I tried following their tutorials on their site, did their quick start stuff as well as read the docs thoroughly, but I keep getting the error above:
"Error: Key content was undefined. Cannot pass undefined in JSON. Use null instead."
I can get it all working in the above plunk, so I understand the concepts. Then I copied that same code from the plunk, and CDN links to my project, same error. Im using ionic framework for a web-based app. Angular and everything is still working fine,I just get the error when trying to hit the "add" button to run the function.
UPDATE: It definitely has something to do with inputs. If I set the "from" and "content" key and field as strings rather than bound to $scope, it works:
$scope.addMessage = function(){
$scope.messages.$add({
from: 'test',
content: 'stuff'
});
$scope.message = '';
};
But obviously that isn't useful other than sending the same data over and over again.
You have your $scope.messages in a form. The form creates a new scope. Remove the form and replace your button with the following:<button ng-click="addMessage()">Add</button>
This doesn't create a new scope and your message will be added successfully to your firebase.
At least it worked for me.
Add the models to the function
$scope.addMessage = function(user,message) {
$scope.messages.$add({
user,
body: message
});
//RESET MESSAGE
$scope.msg = "";
}
and on your form
<label class="item item-input">
<span class="input-label">Name</span>
<input type="text" name="username" ng-model="user" >
</label>
<label class="item item-input">
<span class="input-label">Message</span>
<input type="text" name="password" ng-model="message" >
</label>
<button class="button button-full button-positive" ng-click="addMessage(user,message)"> Send </button></pre>
Best of luck.

Resources