Angular js - Not able to push to an array - javascript

I'm trying to push some info to an array and show it with ng-repeat but for some reason it's not working
This is my controller:
(function () {
'use strict';
angular
.module('app.article')
.controller('Article', Article);
function Article($location) {
var vm = this;
vm.comments = [];
vm.addComment = addComment;
function addComment() {
vm.comments.push(vm.newComment);
vm.newComment = {};
}
}
})();
Here's the plunkr: https://plnkr.co/edit/jPOJDXoG1vgNfsDzyJAD?p=preview
Thanks for the help

for your controller you are using a controller As syntax so you will have to refer to scope variables with a prefix of vm.
<div ng-controller="Article as vm">
<form ng-submit="vm.addComment()">
<textarea placeholder="Sign in to share your thoughts." ng-model="vm.newComment.comment"></textarea>
<input type="text" class="form-control" ng-model="vm.newComment.user">
<input type="submit" class="btn btn-primary" value="Post">
</form>
<ul>
<li ng-repeat="comment in vm.comments">{{comment.user}} - {{comment.comment}}</li>
</ul>
</div>
Also in your controller you have to initialize a newComment object
function Article($location) {
var vm = this;
vm.comments = [];
vm.addComment = addComment;
vm.newComment = {user: '', comment: ''}
function addComment() {
vm.comments.push(vm.newComment);
vm.newComment = {};
}
}
Updated Plunker

<div ng-controller="Article as vm">
<form ng-submit="vm.addComment()">
<textarea placeholder="Sign in to share your thoughts." ng-model="vm.newComment.comment"></textarea>
<input type="text" class="form-control" ng-model="vm.newComment.user">
<input type="submit" class="btn btn-primary" value="Post">
</form>
<ul>
<li ng-repeat="comment in vm.comments">{{comment.user}} - {{comment.comment}}</li>
</ul>
</div>
Here is the updated plunkr
https://plnkr.co/edit/HK4WIYCF6poMXncBU9Uk?p=preview

Related

Call a function from a directive to the controller

I am trying to implement a simple comment writing from client to server using angular.
Here is the HTML for the comment form:
<form id="commentsForm" name="commentsForm" ng-submit="submitComment()">
<fieldset>
<legend>Post a comment</legend>
<div class="form-group comment-group">
<label for="comment" class="control-label">Comment</label>
<div class="control-field">
<textarea class="form-control" cols="30" rows="5" name="comment" id="comment-textarea" tabindex="3" ng-model="c.comment" required></textarea>
</div>
</div>
<div class="form-group button-group">
<div class="control-field">
<button type="submit" class="btn btn-primary btn-comment" tabindex="4" >Post comment</button>
</div>
</div>
</fieldset>
</form>
And the controller I use with the "submitComment()" function:
'use strict';
// inject scope, services (CommentService)
//
angular.module('mean.groups').controller('CommentsCtrl', ['$scope','Global', 'CommentsService', function($scope, CommentsService) {
$scope.c = {};
console.log("controller is online");
$scope.submitComment = function (comment) {
console.log("activted submit comment function");
var postCommentData = {};
postCommentData.postingTime = new Date();
postCommentData.commentData = $scope.c.comment;
console.log("in controller:" + postCommentData);
CommentsService.postComment(postCommentData)
.then(function () {
$scope.commentsForm.$setPristine();
$scope.c = {};
console.log('posted');
});
};
}]);
And the directive I use wrap the html:
'use strict';
angular.module('mean.directives').directive('commentForm', function() {
return {
restrict: 'E',
templateUrl: 'comments/views/comment-form.html',
controller: 'CommentsCtrl',
controllerAs: 'commentsForm'
}
});
The service I use is a standard http.post service but I don't understand why the console.log() in the controller function is not triggered with the comment.
Thanks.
You aren't using the controller, to use the controller add the controllerAs object before the functions.
<form id="commentsForm" name="commentsForm" ng-submit="commentsForm.submitComment()">
<fieldset>
<legend>Post a comment</legend>
<div class="form-group comment-group">
<label for="comment" class="control-label">Comment</label>
<div class="control-field">
<textarea class="form-control" cols="30" rows="5" name="comment" id="comment-textarea" tabindex="3" ng-model="commentsForm.c.comment" required></textarea>
</div>
</div>
<div class="form-group button-group">
<div class="control-field">
<button type="submit" class="btn btn-primary btn-comment" tabindex="4" >Post comment</button>
</div>
</div>
Here is the answer, I just add :
link: function($scope, element, attrs) {
$scope.submitComment = function () {
//my code logic ...
}
}
And changed the replace to false:
replace: false;

Angularjs $setPristine not working with controller as syntax

$setPristine works alright when referenced with $scope but doesn't seem to work with 'controller as syntax'
In View:
<h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
<form name="form1" id="form" novalidate>
<input name="name" ng-model="first.data.name" placeholder="Name" required/>
<button class="button" ng-click="first.reset()">Reset</button>
</form>
<p>Pristine: {{form1.$pristine}}</p>
<p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr>
<h2>With $scope</h2>
<div ng-controller="SecondCtrl">
<form name="form1" id="form" novalidate>
<input name="name" ng-model="data.name" placeholder="Name" required/>
<button class="button" ng-click="reset()">Reset</button>
</form>
<p>Pristine: {{form1.$pristine}}</p>
<p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
In app.js:
var app = angular.module('plunker', []);
app.controller('FirstCtrl', function() {
'use strict';
var vm = this;
vm.data = { "name": ""};
vm.reset = function() {
vm.data.name = "";
vm.form1.$setPristine();
}
});
app.controller('SecondCtrl', function($scope) {
'use strict';
$scope.data = { "name": ""};
$scope.reset = function() {
$scope.data.name = "";
$scope.form1.$setPristine();
}
});
Here is the plunker: http://plnkr.co/edit/VcgZx3?p=preview
Even if you use controller as syntax, the form and other attributes are still bound to the scope not to the controller instance so you still have to use $scope.form1.$setPristine(); to set the form's state.
var app = angular.module('my-app', [], function() {})
app.controller('FirstCtrl', function($scope) {
'use strict';
var vm = this;
vm.data = {
"name": ""
};
vm.reset = function() {
vm.data.name = "";
$scope.form1.$setPristine();
}
});
app.controller('SecondCtrl', function($scope) {
'use strict';
$scope.data = {
"name": ""
};
$scope.reset = function() {
$scope.data.name = "";
$scope.form1.$setPristine();
}
});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<div ng-app="my-app">
<h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
<form name="form1" id="form" novalidate>
<input name="name" ng-model="first.data.name" placeholder="Name" required/>
<button class="button" ng-click="first.reset()">Reset</button>
</form>
<p>Pristine: {{form1.$pristine}}</p>
<p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr/>
<h2>With $scope</h2>
<div ng-controller="SecondCtrl">
<form name="form1" id="form" novalidate>
<input name="name" ng-model="data.name" placeholder="Name" required/>
<button class="button" ng-click="reset()">Reset</button>
</form>
<p>Pristine: {{form1.$pristine}}</p>
<p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
</div>
An alternative to using Arun's suggestion of accessing the form through $scope is simply to ensure the form is accessible through the controller.
To do this all you have to do is change your HTML for the 'controller as' version very slightly. Change the form's name to include the controller object, also change any references to the form from the template to include the controller variable:
<h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
<form name="first.form1" id="form" novalidate>
<input name="name" ng-model="first.data.name" placeholder="Name" required/>
<button class="button" ng-click="first.reset()">Reset</button>
</form>
<p>Pristine: {{first.form1.$pristine}}</p>
<p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr>
Your Javascript will now run unchanged.
I think an even easier way to accomplish this is to provide the form controller as a parameter to the reset() function:
…
<button class="button" ng-click="reset(form1)">Reset</button>
…
and change the reset() function slightly, so that it uses the supplied parameter:
$scope.reset = function(form) {
$scope.data.name = "";
form.$setPristine();
}
You can use $setPristine without $scope:
<form ng-submit="$ctrl.save()" name="$ctrl.myForm">
And in your controller:
var $ctrl = this;
...
$ctrl.myForm.$setPristine();
$ctrl.myForm.$setUntouched();
It works for me. (AngularJS v1.5.7)

Can't access form inside AngularJS controller

Can't access form variable from my controller, when i try to access it by $scope.locationForm i've got 'undefined', but when i call console.log($scope) i can see in console there have loactionForm.
My HTML code
<div ng-controller="LocationsController as ctrl">
<form class="form-inline" name="locationForm">
<div class="form-group">
<!-- <div class="input-group"> -->
<label for="location-name">Название населенного пункта</label>
<input required
name="name"
ng-model="ctrl.location.name" type="text" class="form-control" id="location-name" placeholder="Название населенного пункта">
<label for="location-name">Район</label>
<select required
name="region_id"
ng-model="ctrl.location.region_id"
ng-options="region.id as region.name for region in ctrl.regions" class="form-control" placeholder="Название района"></select>
<input ng-click="ctrl.save()"
ng-disabled="locationForm.$invalid" type="submit" class="btn btn-default" value="Cохранить">
<a class="btn btn-default" ng-click="ctrl.reset()" ng-show="locationForm.$dirty">Сброс</a>
<!-- </div> -->
</div>
</form>
My Controller code:
function LocationsController($scope, Location, Region, $q) {
var lc = this,
l_index;
lc.form ={};
lc.regions = lc.locations = [];
lc.regions = Region.query();
lc.regions.$promise.then(function(data) {
lc.locations = Location.query();
});
lc.getRegion = function (id) {
return lc.regions.filter(function(obj) {
return obj.id == id;
})[0].name;
};
console.log($scope);
// console.log($scope.locationForm);
lc.reset = function () {
lc.location = new Location;
}
lc.reset();
};
The problem is when the LocationsController is initialized the form element is not yet compiled. So one possible hack is to use a timeout like
function LocationsController($scope, Location, Region, $q, $timeout) {
//then later
$timeout(function(){lc.reset();})
}

how to create object while using ng-repeat and array in angularjs

Hello Everyone I have face a problem to create a object with ng-repeat. when i declare the Object then the same value in filled in the text box which has same ng-model value. if i am not Declare the object then duplicacy is not occures.
If i am declare the $scope.user = {}; in js file then problem is occures. please check this. Give me a solution ASAP.
My Fiddle Link Please Check This http://jsfiddle.net/Ladjkp5s/1/
Here is my Html file
<div ng-app="myApp">
<div ng-controller='MainController' ng-init="start = 0; end = 5;">
Start: <input ng-model="start"> End: <input ng-model="end">
<ul>
<li ng-repeat="item in items | slice:start:end">{{item + 1}}
<div>
Name: <input type="text" ng-model="user.name"><br>
Address: <input type="text" ng-model="user.add"><br>
Phone: <input type="text" ng-model="user.phn"><br>
ZipCode: <input type="text" ng-model="user.zip">
</div>
</li>
</ul>
</div>
</div>
Here is my JS File
var app = angular.module('myApp', []);
app.filter('slice', function() {
return function(arr, start, end) {
return arr.slice(start, end);
};
});
app.controller('MainController', function($scope) {
$scope.items = [];
$scope.user ={};
for (var i = 0; i < 5; i++) $scope.items.push(i);
});
Thanks.
The problem is that you are using same ng-model for every item.(user.fieldName) you have to use item.fieldName.
<div ng-app="myApp">
<div ng-controller='MainController' ng-init="start = 0; end = 5;">
Start: <input ng-model="start"> End: <input ng-model="end">
<ul>
<li ng-repeat="item in items | slice:start:end">{{item.index + 1}}
<div>
Name: <input type="text" ng-model="item.name"><br>
Address: <input type="text" ng-model="item.add"><br>
Phone: <input type="text" ng-model="item.phn"><br>
ZipCode: <input type="text" ng-model="item.zip">
</div>
</li>
</ul>
</div>
</div>
http://jsfiddle.net/3akwk7tv/
Yuu can not loop in controller function, but u can create controller that loops in html like in this example
<ul>
<li ng-repeat="theItem in myData.items">{{theItem.text}}</li>
</ul>
<script>
angular.module("myapp", [])
.controller("MyController", function($scope) {
$scope.myData = {};
$scope.myData.items = [ {text : "one"}, {text : "two"}, {text : "three"} ];
});
</script>

ng-click does nothing (todo list example)

I try to play around with some test in angular. but failed to add item in a todo list app sample:
app.controller('MainControl', function($scope){
$scope.tasks = [
{
"name":"task 1",
},
{"name":"task 2",
}
];
var addTask = function(){
$scope.tasks.push({
"name": $scope.input,
});
$scope.input = "";
};
});
I wonder why it doesn't work, no error in the console.
my html
<body ng-controller="MainControl">
<div>
<label>I want to:</label>
<input type="text" ng-model="input">
<button ng-click="addTask()">Add</button>
</div>
<div>
<ul ng-repeat="task in tasks">
<li>{{task.name}}</li>
</ul>
</div>
</body>
addTask must be a $scope property, i.e. $scope.addTask = function() {} instead of var addTask = function() {}.
Edit after comments:
<form ng-submit="addTask()">
<label>I want to:</label>
<input type="text" ng-model="input">
<button type="submit">Add</button>
</form>

Categories