One value won't save in AngularJS - angularjs

For some reason the comment.content part turns out to be null every time I try to save it, but the comment.pid works just fine, why is that? It's really not making sense to me.
The controller:
var CreateCommentController = function ($scope, $location, $routeParams, Comment) {
$scope.action = "Create";
var id = $routeParams.postId;
var content = $scope.content;
var comment = new Comment();
comment.pid = id;
comment.content = content;
$scope.save = function () {
Comment.save(comment, function () {
$location = '/';
});
}
};
The HTML:
<div class="control-group" ng-class="{error: form.content.$invalid}">
<label class="control-label lbl" for="content">Content:</label>
<div class="controls">
<textarea ng-model="content" id="content" class="textareaContent">content</textarea>
</div>

Try ng-model="comment.content" directive on the textarea. Also you should remove the optional content you provided between the opening and closing textarea tags. If you want to initialize it with some default content that should be done on the model:
<textarea ng-model="comment.content" id="content" class="textareaContent" ></textarea>
Also you might need to pass the comment instance in the scope:
$scope.comment = comment;

Related

How to show value in input field with ng-model?

I created edit form so I have to include default value for each text field. I wrote this HTML code:
<input type="text" ng-model="projectData.title" ng-init="projectData.title=title" name="title" class="form-control" />
In controller:
$scope.title = "This is just title";
It shows nothing in the text box. I tried ng-init="projectData.title={{title}}" and ng-init="projectData.title='title'" but it's just not working.
I'm using angularjs 1.6 and the following solution is not working too.
http://jsfiddle.net/Aejvm/337/
In your scope, you should declare the object like so:
$scope.projectData = {};
$scope.projectData.title = "This is just title";
Check This [Code][1]
[1]: http://jsfiddle.net/d4ts76ys/
Use the object to map it to ng-model
Well you are doing a little wrong.
ng-init is angular directive and you dont need curly braces.
modify your code to this :
html:
<div ng-controller="MyCtrl">
<input type="text" ng-init="rootFolders.name=name" ng-
model="rootFolders.name" >
<br>rootFolders={{name}}
</div>
js:
var app = angular.module('myApp',[]);
app.controller('MyCtrl', function($scope) {
$scope.name = "Acunisasi";
});
I have created fiddle that may help your
jsfiddle
//html
<div ng-controller='MyCtrl'>
<form>
<input ng-init="projectData.title = title" type="text" ng-model="title">
<button ng-click="formSubmit()">
submit
</button>
</form>
{{title}}
</div>
//js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', MyController]);
function MyController($scope) {
$scope.projectData = {};
$scope.title = 'This is just title';
$scope.formSubmit = function() {
console.log("$scope.projectData ===>", $scope.projectData)
}
}

Angular updating and clearing factory variables

I'm creating a single page app in which a user searches for a term, the result gets saved in a variable, and a new page is routed that displays the result. I have this functionality working, however I want the variable to be cleared when the user returns to the previous page and most importantly when the user logs out. What's the proper way to do this? I want the factory to save things for certain pages that I want, and clear them for certain pages I don't want like "home" or "logout".
Factory:
angular.module('firstApp')
.factory('fact', function () {
var service = {};
var _information = 'Default Info';
service.setInformation = function(info){
_information = info;
}
service.getInformation = function(){
return _information;
}
return service;
});
Controller:
angular.module('firstApp')
.controller('InformationCtrl', function($scope, $http, $location, fact) {
$scope.message = 'Hello';
$scope.result = fact.getInformation();
$scope.sub = function(form) {
console.log($scope.name);
$scope.submitted = true;
$http.get('/wiki', {
params: {
name: $scope.name,
}
}).success(function(result) {
console.log("success!");
$scope.result = result;
fact.setInformation(result);
$location.path('/informationdisplay');
});;
}
});
Routes
angular.module('firstApp')
.config(function ($routeProvider) {
$routeProvider
.when('/information', {
templateUrl: 'app/information/input.html',
controller: 'InformationCtrl',
authenticate : true
})
.when('/informationdisplay', {
templateUrl: 'app/information/results.html',
controller: 'InformationCtrl',
authenticate : true
});
});
input.html
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>{{result}}</p>
<form class="form" name="form" ng-submit="sub(form)" novalidate>
<input type="text" name="name" placeholder="Name" class="form-control" ng-model="name">
</br>
<button class="btn btn-success" type="submit" class="btn btn-info">Check</button>
</div>
</div>
results.html
<div ng-include="'components/navbar/navbar.html'"></div>
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
<h2>Information Results</h2>
<p>{{result}}</p>
</div>
</div>
</div>
If you want it to wipe the value when they change routes (which logout should change routes also, I assume), you can watch the $routeChangeStart event and have it wipe the value whenever it occurs. You put that function in the module.run block:
app.run(function ($rootScope, fact) {
$rootScope.$on("$routeChangeStart",function(event, next, current){
fact.setInformation(null);
});
});

AngularJS - directive with a dynamic array of objects in form

I'm trying to create a form that has a dynamic set of input boxes. I'm trying to get ng-models to work with array items and I am clearly doing something wrong.
My problem seems to be indexing the scope array lineItems in the template.
Here is my jsfiddle: http://jsfiddle.net/dk253/9ykuuobq/
Here is my code:
<div ng-controller="MyCtrl">
<h2>Testing Arrays</h2>
<button type="button" ng-click="addItem()" class="btn btn-primary">Howdy</button>
<div ng-repeat="item in items" item="item" my-index="{{$index}}" itemlist></div>
</div>
<script type="text/ng-template" id="template.html">
<div class = "row">
<div class = "col-xs-6"> <input name= "itemNum-{{item.itemNum}}" type = "number" class="form-control"
placeholder = "Item Number" ng-model="items[{{item.itemNum}}].itemNum" required> </div>
<div class = "col-xs-6"> <input name= "name-{{item.itemNum}}" type = "text" class="form-control"
placeholder = "Name" ng-model="items[{{item.itemNum}}].name" required> </div>
</div>
</script>
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.count = 0;
$scope.items = [];
var baseItem = {
itemNum: 0,
name: "New"
};
$scope.addItem = function () {
newItem.itemNum = $scope.count;
var newItem = angular.copy(baseItem);
newItem.itemNum = $scope.count;
$scope.items.push(newItem);
$scope.count += 1;
};
});
myApp.directive('itemlist', function ($compile) {
return {
templateUrl: 'template.html',
restrict: 'A',
replace: true,
transclude: true,
scope: { item: '=', myIndex: '#' }
};
});
Thanks for your help!
The fiddle has several mistakes:
$scope.addItem is using the newItem before defining it. Remove the first line (probably a typo).
The ng-model:
It accepts expressions without {{...}}. So ng-model="items[{{item.itemNum}}].itemNum" would become ng-model="items[item.itemNum].itemNum"
This is still wrong because the directive has isolated scope and the items variable is not visible. But item is visible, so you only need: ng-model="item.itemNum" (and ng-model="item.name").
With these changes, it seems to be working: http://jsfiddle.net/9ykuuobq/19/

formData not changing with ngChange hook

I have a very basic scenario where in which I have a module with one controller:
var myModule = angular.module('myModule', []);
myModule.controller('myModuleCtrl', function ($scope, $http) {
$scope.formData = {url:'',title:'',source:''};
$scope.init = function() {
$scope.formData.url = 'Test';
$scope.formData.title = '';
$scope.formData.source = '';
};
$scope.manageUrl = function() {
alert('update');
};
});
In my view I'm trying to hook the formData object properties to some form fields using ngModel. However my input doesn't update it's value after the init() method runs. If I add the ngChange directive and hook that up with the $scope.manageUrl() method, it only runs once, after my first keystroke/change of the input.
Am I missing something here? I've used both directives before without any problems. Only thing I can think of is something wrong with my module/controller setup?
This is what my view looks like:
<div ng-app="myApp" ng-controller="myModuleCtrl" ng-init="init()">
<div>
<form name="myForm">
<div>
<input type="url" ng-model="formData.url" ng-change="manageUrl()" />
</div>
</form>
</div>
</div>
And my application.js bootstrapper:
var app = angular.module('myApp', ['myModule']);
It happens because of the url validator, note how the whole url property is removed until you enter a valid url, that's when you'll start to get your alerts back. Basically, once removed, the url is never considered to be changed until a valid (and different) url is input.
url is set to 'Test'
you type anything into the box, it fails the validation and becomes undefined
it stays undefined until you enter a valid url (it's not changing)
Start typing http://anything and see what happens yourself:
var myModule = angular.module('myModule', []);
myModule.controller('myModuleCtrl', function ($scope, $http) {
$scope.formData = {url:'',title:'',source:''};
$scope.init = function() {
$scope.formData.url = 'Test';
$scope.formData.title = '';
$scope.formData.source = '';
};
$scope.manageUrl = function() {
alert('update');
};
});
var app = angular.module('myApp', ['myModule']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myModuleCtrl" ng-init="init()">
<div>
<form name="myForm">
<div>
<input type="url" ng-model="formData.url" ng-change="manageUrl()" />
<br>
{{formData}}
</div>
</form>
</div>
</div>
Am I missing something here? I've used both directives before without any problems. Only thing I can think of is something wrong with my module/controller setup?
The only logical solution that comes to my mind is that you've used a different input type before, so you were not a subject to validations. If you change the type to text, it works fine the whole time.

AngularJS data binding in controller

This works great:
<input type="text" class="search" data-ng-model="name"/>
<div class="rf-contact" data-ng-repeat="contact in contacts | filter: name">
<p class="rf-first">{{contact.first_name}} {{contact.last_name}}</p>
</div>
However I need to implement filter in the controller:
var contactsController = function ($scope, $filter){
$scope.contacts = contacts;
$scope.filteredContacts = $filter('filter')($scope.contacts, $scope.name);
}
<input type="text" class="search" data-ng-model="name"/>
<div class="rf-contact" data-ng-repeat="contact in filteredContacts">
<p class="rf-first">{{contact.first_name}} {{contact.last_name}}</p>
</div>
The problem with the code above is that the data binding is lost. When the data is changing in the text field, the filtering is not happening. Do I need to explicitly set event listeners for the input field in my controller? thanks.
You could try $watch-ing the name:
var contactsController = function ($scope, $filter){
$scope.contacts = contacts;
$scope.filteredContacts = $filter('filter')($scope.contacts, $scope.name);
$scope.$watch('name', function(newValue, oldValue) {
$scope.filteredContacts = $filter('filter')($scope.contacts, newValue);
});
}
For more info on $watch: http://docs.angularjs.org/api/ng/type/$rootScope.Scope. Anytime "something" happens through Angular (like the value of "name" changes because you type something in the text field), Angular will fire the watch you created and execute the function. This is necessary here because the initial code you wrote builds the filteredContacts scope variable when the controller is instantiated and there's nothing re-evaluating this expression.
While this solution with an explicit $watch will work, it's a little hacky. This kind of logic is better encapsulated in a custom filter. You can easily build one with arbitraty logic as described in http://docs.angularjs.org/tutorial/step_09.
Try the following
var contactsController = function ($scope, $filter){
$scope.filterContacts = function(){
$scope.contacts = contacts;
$scope.filteredContacts = $filter('filter')($scope.contacts, $scope.name);
}
}
<input type="text" class="search" data-ng-model="name" ng-change="filterContacts()"/>
<div class="rf-contact" data-ng-repeat="contact in filteredContacts">
<p class="rf-first">{{contact.first_name}} {{contact.last_name}}</p>
</div>
Here's a jsfiddle of this in action:
http://jsfiddle.net/CAuq9/

Resources