Why does the push function affects other objects in an array? - arrays

There is a problem in my app: I'm trying to push the note array into the notes array, but when the second array is pushed into notes, all objects in the notes are become the same.
This is my angularJS controller:
var app = angular.module("myApp", []);
app.controller("noteCtrl", function ($scope) {
$scope.note = {};
$scope.notes = [];
$scope.submit = function() {
$scope.notes.push($scope.note);
};
});
Html code:
<div data-ng-controller="noteCtrl">
<form name="noteForm" data-ng-submit="submit()">
<div class="col-md-9 col-sm-12 col-xs-12">
<div class="row">
<div class="col-xs-12 bdr">
<input class="full" type="text" name="title" data-ng-model="note.title" placeholder="Note title is required" required />
</div>
</div>
<div class="row">
<div class="col-xs-12 bdr">
<textarea class="full" name="content" data-ng-model="note.content" placeholder="Input the note content here"></textarea>
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12 bdr">
<button class="full" type="reset" data-ng-click="">Cancel</button>
</div>
<div class="col-md-4 col-sm-4 col-xs-12 bdr">
<button class="full" type="button" data-ng-disabled="noteForm.$invalid" data-ng-click="">Save</button>
</div>
<div class="col-md-4 col-sm-4 col-xs-12 bdr">
<button class="full" type="submit" data-ng-disabled="noteForm.$invalid">Publish</button>
</div>
</div>
</div>
</form>
{{note}}
{{notes}}
</div>
For example, I push two different object (with different values of course) into the notes. After the second one is pushed into it, the notes would look like this:
[{"title":"aaaa","content":"bbbb"},{"title":"aaaa","content":"bbbb"}]
Thanks in advance.

I think the note should have properties initially and after push it should be reset.
app.controller("noteCtrl", function ($scope) {
$scope.note = { title: "", content: "" };
$scope.notes = [];
$scope.submit = function() {
$scope.notes.push($scope.note);
$scope.note = { title: "", content: "" };
};
});

That is for scope of object. you should define object in function body.
$scope.submit = function() {
var note = {"title":"","content":""};
$scope.notes.push(note);
};

Related

AngularJs hide all alerts: Uncaught SyntaxError

I have an angularJS component that displays alerts when something goes wrong while submitting, these alerts are not auto dismissed by design.
But, when the user fix all errors (there can be many alerts displayed on the screen) and submit I want to dismiss these alerts.
Based on this example https://jsfiddle.net/uberspeck/j46Yh/
I did something like this:
(function(){
var mainApp = angular.module("myApp");
function AlertsCtrl($scope, alertsManager) {
$scope.alerts = alertsManager.alerts;
}
mainApp.factory('alertsManager', function() {
return {
alerts: {},
addAlert: function(message, type) {
this.alerts[type] = this.alerts[type] || [];
this.alerts[type].push(message);
},
clearAlerts: function() {
for(var x in this.alerts) {
delete this.alerts[x];
}
}
};
mainApp.controller("addUserCtrl", ['Restangular', 'alertsManager', '$alert', 'roles', '$window' , function(Restangular, alertsManager, $alert, roles, $window) {
var that = this;
init();
that.submit = function() {
var data = {
user : that.name,
role : that.role.serverName,
credentials : that.password1
}
Restangular.all("admin").all("user").all("add").post(data).then(function() {
//$alert({title: 'Add User:', content: 'Completed succefully', type: 'success', container: '#alert', duration: 5, show: true});
alertsManager.addAlert('Completed succefully', 'alert-success');
init();
alertsManager.clearAlerts();
}, function(reason) {
//$alerts{title: 'Add User:', content: reason.data.error, type: 'danger', container: '#alert', show: true});
alertsManager.addAlert(reason.data.error, 'alert-error');
});
}
function init() {
that.name = "";
that.roles = roles;
that.role = that.roles[0];
that.password1 = "";
that.password2 = "";
}
}]);
})();
HTML:
<div ng-controller="addUserCtrl as ctrl">
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<form class="form-horizontal" ng-submit="ctrl.submit()">
<div class="panel-heading">Add User</div>
<div class="panel-body">
<div class="form-group">
<label for="name" class="col-sm-3 control-label">User Name: <span class="required">*</span></label>
<div class="col-sm-8">
<input type="text" class="form-control" id="name" ng-model="ctrl.name"></input>
</div>
</div>
<div class="form-group">
<label for="role" class="col-sm-3 control-label">Role: <span class="required">*</span></label>
<div class="col-sm-8">
<select class="form-control" id="role" ng-model="ctrl.role" ng-options="opt.displayName for opt in ctrl.roles"></select>
</div>
</div>
<div class="form-group">
<label for="password1" class="col-sm-3 control-label">Password: <span class="required">*</span></label>
<div class="col-sm-8">
<input type="password" class="form-control" id="password1" ng-model="ctrl.password1"></input>
</div>
</div>
<div class="form-group">
<label for="password2" class="col-sm-3 control-label">Re-enter Password: <span class="required">*</span></label>
<div class="col-sm-8" ng-class="{'has-error' : ctrl.password1 != ctrl.password2}">
<input type="password" class="form-control" id="password2" ng-model="ctrl.password2"></input>
<p class="help-block" ng-if="ctrl.password1 != ctrl.password2">Passwords don't match</p>
</div>
</div>
</div>
<div class="panel-footer">
<button type="submit" class="btn btn-default" ng-disabled="!ctrl.name || !ctrl.password1 || !ctrl.password2 || ctrl.password1 != ctrl.password2">OK</button>
</div>
<div ng-controller="AlertsCtrl">
<div ng-repeat="(key,val) in alerts" class="alert {{key}}">
<div ng-repeat="msg in val">{{msg}}</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
But I'm getting:
Uncaught SyntaxError: Unexpected end of input
angular.js:14747 Error: [ng:areq] http://errors.angularjs.org/1.4.3/ng/areq?p0=addUserCtrl&p1=not%20aNaNunction%2C%20got%20undefined
You did not complete all brackets correctly.
Below should be like this:
mainApp.factory('alertsManager', function() {
return {
alerts: {},
addAlert: function(message, type) {
this.alerts[type] = this.alerts[type] || [];
this.alerts[type].push(message);
},
clearAlerts: function() {
for(var x in this.alerts) {
delete this.alerts[x];
}
}
}
});
You forgot to complete the factory by });.
And that is why indentation is so important.
Hope this may help you.

How to delay my ng-init function until my api call is success

I am working on dynamic form with ng-repeat. I am using oi-select for loading my location. I am loading this form inside modal popup. Regarding get my location values i am calling one api function on click of my modal open button. On success of this api call i was calling ng-init method. As per my requirement i should make this api call on click of modal open button. If i am clicking that button at first time, by default my first location value is not loaded inside select-box. Because my ng-init function called before my api call. Other than first time its working fine. Only first time it was not loaded that location[0] value defaultly . My question is how to delay this ng-init function?. Is there any other way to resolve this issue. Here i attached my plunker link .Please help me out from this issue. https://plnkr.co/edit/xDVetaZIzpFdKLS9ihU6?p=preview
html code
<body class="container row">
<div ng-app="myApp">
<div ng-controller="myCtrl">
<a class="btn btn-primary" data-toggle="modal" href='#modal-id' ng-click="getLocation()">Trigger modal</a>
<div class="modal fade" id="modal-id">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<form role="form" name='userForm' novalidate>
<div class="container">
<div class="row" ng-repeat="user in users">
<div class="form-group">
<div class="col-md-3">
<label>ID</label>
<input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
</div>
<div class="col-md-3">
<label>Comments</label>
<textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
</div>
<div class="col-md-3 ">
<label>Location</label>
<oi-select ng-model="user.location" multiple oi-options="v for v in locations" ng-init='initLocation(user, locations)' name="select2" required>
</oi-select>
</div>
</div>
</div>
</div>
<div class="buttonContainer text-center btn-container">
<br>
<button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
<button type="button" class="btn button--default btn--small pull-center">Close</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</div>
</div>
js code
var app = angular.module('myApp', ['ngResource', 'oi.select']);
app.factory('commonService', function($http, $q) {
return {
preFCSManualReleases: function() {
var deferred = $q.defer();
var url = "data.json";
$http.get(url, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: ''
}).then(function(data) {
deferred.resolve(data.data);
});
return deferred.promise;
}
}
});
app.controller('myCtrl', function($scope, commonService) {
$scope.getLocation = function() {
$scope.ids = [1, 2];
commonService.preFCSManualReleases().then(function(data) {
$scope.locations = data;
console.log('$scope.location[0]==============>', $scope.locations[0])
$scope.initLocation = (user, locations) => {
if (!user.location.length) {
user.location.push(locations[0]);
}
}
});
$scope.users = $scope.ids.map(function(id) {
return {
id: id,
comment: "",
location: []
};
});
}
$scope.adduser = function() {
var data = $scope.users.map(function(user) {
return {
"userid": user.id,
"manualcomment": user.comment,
"location": user.location
}
});
console.log("data", data)
}
});
You can put a condition on the oi-select parent:
<div class="col-md-3" ng-if="locationsLoaded">
<label>Location</label>
<oi-select ng-model="user.location" multiple oi-options="v for v in locations" ng-init='initLocation(user, locations)' name="select2" required>
</oi-select>
</div>
You can then control the $scope.locationsLoaded in your controller:
$scope.getLocation = function() {
$scope.locationsLoaded = false;
commonService.preFCSManualReleases().then(function(data) {
$scope.locations = data;
console.log('$scope.location[0]==============>', $scope.locations[0])
$scope.initLocation = (user, locations) => {
if (!user.location.length) {
user.location.push(locations[0]);
}
}
$scope.locationsLoaded = true; // we now have the required data
});
}
The ng-if will compile the element once locationsLoaded is true and when the ng-init is triggered, you are sure that there is data.

angular form ng-repeat deleting single form

i am working with dynamic forms with ng-repeat .i am getting dynamic forms according to my userid. each form has delete button. my requirement is once i am clicking delete button i need to delete that particular form and those values from my user obj and remaining values i need to send to server. in this example i want to delete id 2 (2nd form), and 1st and 2nd form data i need to store one variable.
please send some fiddle for this .
my html code
<div ng-app="myApp">
<div ng-controller="myCtrl">
<form role="form" name='userForm' novalidate>
<div class="container">
<div class="row" ng-repeat="user in users">
<div class="form-group">
<div class="col-md-3">
<label>ID</label>
<input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
</div>
<div class="col-md-3">
<label>Comments</label>
<textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
</div>
<div class="col-md-3 ">
<label>Location</label>
<select ng-model="user.location" ng-options="v for v in locations" ng-init='initLocation(user)' name="select2" required>
</select>
</div>
<div>
<button>delete</button>
</div>
</div>
</div>
</div>
<div class="buttonContainer text-center btn-container">
<br>
<button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
<button type="button" class="btn button--default btn--small pull-center">Close</button>
</div>
</form>
</div>
js file
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope, $timeout) {
$scope.ids = [1, 2, 3];
$scope.users = $scope.ids.map(function(id) {
return {
id: id,
comment: "",
location: ""
};
});
$scope.locations = ['india', 'usa', 'jermany', 'china', 'Dubai'];
$scope.initLocation = (user) => {
$timeout(() => {
user.location = $scope.locations[0];
});
}
$scope.adduser = function() {
var data = $scope.users.map(function(user) {
return {
"userid": user.id,
"manualcomment": user.comment,
"location": user.location
}
});
console.log("data", data)
}
});
As per your requirement i am adding ng-click to delete button and adding removeSelForm method and pass your user object into that function parameter. in controller i am removing that particular form values from users object.
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope, $timeout) {
$scope.ids = [1, 2, 3];
$scope.users = $scope.ids.map(function(id) {
return {
id: id,
comment: "",
location: ""
};
});
$scope.locations = ['india', 'usa', 'jermany', 'china', 'Dubai'];
$scope.initLocation = (user) => {
$timeout(() => {
user.location = $scope.locations[0];
});
}
$scope.removeSelForm = function(item) {
var index = $scope.users.indexOf(item)
$scope.users.splice(index, 1);
}
$scope.adduser = function() {
var data = $scope.users.map(function(user) {
return {
"userid": user.id,
"manualcomment": user.comment,
"location": user.location
}
});
console.log("data", data)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<form role="form" name='userForm' novalidate>
<div class="container">
<div class="row" ng-repeat="user in users">
<div class="form-group">
<div class="col-md-3">
<label>ID</label>
<input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
</div>
<div class="col-md-3">
<label>Comments</label>
<textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
</div>
<div class="col-md-3 ">
<label>Location</label>
<select ng-model="user.location" ng-options="v for v in locations" ng-init='initLocation(user)' name="select2" required>
</select>
</div>
<div>
<button ng-click="removeSelForm(user)">delete</button>
</div>
</div>
</div>
</div>
<div class="buttonContainer text-center btn-container">
<br>
<button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
<button type="button" class="btn button--default btn--small pull-center">Close</button>
</div>
</form>
</div>

Angularjs radio button value used in api link

I want to use the value of a radio button and implement that into an api link but its not linking for some reason.
heres my code
JS
myApp.controller('HomeController', ['$scope', '$http',
function($scope, $http) {
$scope.formData = {};
$scope.doIt = function() {
$scope.targetURL = ('https://api.api/' + $scope.formData + '/us/profile');
$http.get($scope.targetURL)
.success(function(results) {
$scope.data = results.data;
});
};
}
]);
HTML
<div class="container-fluid">
<div class="background">
<div class="transbox">
<div class="row">
<div class="col-lg-4">
</div>
<div class="col-lg-3">
<label><input type="radio" name='radio' value="pc" ng-model="formData"><img src="../img/battlenet.png"></label>
<label><input type="radio" name='radio' value="psn" ng-model="formData"><img src="../img/playstation.png"></label>
</div>
<div class="col-lg-5">
</div>
</div>
<div class="row">
<div class="col-lg-9">
<input class="form-control" type="text" placeholder="Enter Gamertag">
</div>
<div class="col-lg-3">
<button type="submit" class="btn btn-default" ng-click="doIt()"> Submit </button>
</div>
</div>
</div>
</div>
This works well fiddle:
myApp.controller('HomeController', ['$scope', '$http',
function($scope, $http) {
$scope.formData = {};
$scope.doIt = function() {
$scope.targetURL = ('https://api.api/' + $scope.formData + '/us/profile');
$http.get($scope.targetURL)
.success(function(results) {
$scope.data = results.data;
});
};
}
]);
And your HTML:
<div ng-app="myApp">
<div ng-controller="HomeController">
<div class="container-fluid">
<div class="background">
<div class="transbox">
<div class="row">
<div class="col-lg-4">
</div>
<div class="col-lg-3">
<label><input type="radio" name='radio' value="pc" ng-model="formData"><img src="../img/battlenet.png"></label>
<label><input type="radio" name='radio' value="psn" ng-model="formData"><img src="../img/playstation.png"></label>
</div>
<div class="col-lg-5">
</div>
</div>
<div class="row">
<div class="col-lg-9">
<input class="form-control" type="text" placeholder="Enter Gamertag">
</div>
<div class="col-lg-3">
<button type="submit" class="btn btn-default" ng-click="doIt()"> Submit </button>
</div>
</div>
</div>
</div>
</div>
</div>
I think you are not calling the controller, at least in your example it is not. If you check the network tab in the chrome console for the requests, you will see the correct data is sent:
https://api.api/pc/us/profile
https://api.api/psn/us/profile

Getting form values

angular.module('app', [])
.controller('mainCtrl', ['$scope', function ($scope) {
$scope.checkVal = function () {
console.log('entered');
console.log($scope.data.user)
}
$scope.data = {
//to keep the data from the api or any static data
//this will used to show the data in the view
user: {
fname: '',
lname: '',
email: '',
password: ''
}
};
$scope.methods = {
//this will called from the views to interact with properties and data
//use methods to change the values
checkVal: function () {
console.log('entered');
console.log($scope.data.user)
},
};
$scope.properties = {
//only to change views for ng-if and ng-show
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div action="#" ng-controller="mainCtrl as ctrl">
<div id="modal-login" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form action="#home" ng-submit="ctrl.methods.checkVal()">
<div class="modal-body">
<div class="form-group">
<input ng-model="ctrl.data.user.email" type="text" name="user-email" placeholder="Email:" required>
</div>
<div class="form-group">
<input ng-model="ctrl.data.user.password" type="password" name="password" placeholder="Password:" required>
</div>
</div>
<div class="modal-footer">
<div class="form-group clearfix">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
I am trying to insert the values from the form in the object that i created in the controller. But somehow it isn't doing that. I don't understand why the data binding of this form doesn't give the output in the console like i asked it to. What am i doing wrong?
html
<body>
<div action="#" ng-controller="mainCtrl as ctrl">
<div id="modal-login" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form action="#home" ng-submit="ctrl.methods.checkVal()">
<div class="modal-body">
<div class="form-group">
<input ng-model="ctrl.data.user.email" type="text" name="user-email" placeholder="Email:" required>
</div>
<div class="form-group">
<input ng-model="ctrl.data.user.password" type="password" name="password" placeholder="Password:" required>
</div>
</div>
<div class="modal-footer">
<div class="form-group clearfix">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
js
angular.module('app', [])
.controller('mainCtrl', ['$scope', function ($scope) {
$scope.checkVal = function () {
console.log('entered');
console.log($scope.data.user)
}
$scope.data = {
//to keep the data from the api or any static data
//this will used to show the data in the view
user: {
fname: '',
lname: '',
email: '',
password: ''
}
};
$scope.methods = {
//this will called from the views to interact with properties and data
//use methods to change the values
checkVal: function () {
console.log('entered');
console.log($scope.data.user)
},
};
$scope.properties = {
//only to change views for ng-if and ng-show
}
}])
becaues you use controllerAs in view you must use this format
angular.module('app', [])
.controller('mainCtrl', ['$scope', function ($scope) {
var vm = this;
vm.checkVal = function () {
console.log('entered');
console.log($scope.data.user)
}
vm.data = {
//to keep the data from the api or any static data
//this will used to show the data in the view
user: {
fname: '',
lname: '',
email: '',
password: ''
}
};
vm.methods = {
//this will called from the views to interact with properties and data
//use methods to change the values
checkVal: function () {
console.log('entered');
console.log($scope.data.user)
},
};
vm.properties = {
//only to change views for ng-if and ng-show
}
Try this.
JSFiddle
<script>
angular.module('app', [])
.controller('mainCtrl', ['$scope', function ($scope) {
$scope.checkVal = function () {
console.log('entered');
console.log($scope.data.user)
}
$scope.data = {
//to keep the data from the api or any static data
//this will used to show the data in the view
user: {
fname: '',
lname: '',
email: '',
password: ''
}
};
$scope.methods = {
//this will called from the views to interact with properties and data
//use methods to change the values
checkVal: function (ctrl) {
console.log('entered');
console.log(ctrl)
},
};
$scope.properties = {
//only to change views for ng-if and ng-show
}
}])
</script>
<body ng-app="app">
<div action="#" ng-controller="mainCtrl as ctrl">
<div id="modal-login" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form ng-submit="methods.checkVal(data)">
<div class="modal-body">
<div class="form-group">
<input ng-model="data.user.email" type="text" name="user-email" placeholder="Email:" required>
</div>
<div class="form-group">
<input ng-model="data.user.password" type="password" name="password" placeholder="Password:" required>
</div>
</div>
<div class="modal-footer">
<div class="form-group clearfix">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>

Resources