AngularJS Duplicate key array in a repeater - angularjs

Hi currently i´m programming a application in AngularJs with api rest, but there is something that i miss.
Customers can create organizations with their branchoffices. To create and show the organizations and branchoffices i use the code below.
when the user create an organization there isn´t any problem, but when the user create the second one, the code update the first entry and generate as second one with the same value. so you hava a duplicate key.
What i´m doing wrong?
below you can see the code and pictures attached
First time introduce data and send api, but second time appear the same text. I introduce the new value and send to api rest, and api answer with a right values, but myorganizations variable has the duplicate key with the new value.
First time
Second time
Results
HTML File
<div class="row">
<h4>Mis Organizaciones <small><span class="glyphicon glyphicon-plus"></span></small></h4>
</div>
<div class="row" ng-repeat="organization in myorganizations.data">
<h5>{{organization.company_name}}</h5>
<div ng-repeat="branch in organization.branches">
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 ">
<div class="thumbnail">
<a ui-sref="mybranchoffice({name: '{{branch.branch_name}}', id: '{{branch.branch_id}}', company_id: '{{organization.company_id}}'})">
<div class="thumbnail-organization" style="background: url({{branch.branch_image_url}}) center center no-repeat;"></div>
</a>
<div class="caption">
<h6 class="thumbnail-organization-name"></h6>
</div>
</div>
</div>
<div class="clearfix visible-sm" ng-if="($index+1)%2==0"></div>
<div class="clearfix visible-md" ng-if="($index+1)%3==0"></div>
<div class="clearfix visible-lg" ng-if="($index+1)%4==0"></div>
</div>
<div class="col-lg-5 col-md-5 col-sm-6 col-xs-12">
<div class="jumbotron">
<a type="button" href="" data-company="{{organization.company_id}}" data-toggle="modal" data-target="#branchModal">Create new Branch</a>
</div>
</div>
</div>
<div class="row col-lg-5 col-md-5 col-sm-6 col-xs-12">
<div class="jumbotron">
<a type="button" href="" data-toggle="modal" data-target="#organizationModal" >Create new Organization</a>
</div>
</div>
</div>
Controller
$scope.newOrganization = function () {
butlerService.createOrganization($scope.organization).then(function(neworganization){
console.log(neworganization);
tmp.data[0].company_id = neworganization.data.company_id;
tmp.data[0].company_name = neworganization.data.company_name;
tmp.data[0].branches=[];
console.log(tmp);
$scope.myorganizations.data.push(tmp.data[0]);
console.log($scope.myorganizations);
}), function (error){
}
}
Service
createOrganization: function (organization) {
var deferred = $q.defer();
$http({
method: "post",
url: urlCreateOrganization,
data: organization
})
.success(function(response){
deferred.resolve(response);
})
.error(function(err){
deferred.reject(err);
});
return deferred.promise;
}

Without seeing your variable init it is hard to say for sure, but it seems that here:
tmp.data[0].company_id = neworganization.data.company_id;
tmp.data[0].company_name = neworganization.data.company_name;
tmp.data[0].branches=[];
you are rewriting over the first element in your array. And here:
$scope.myorganizations.data.push(tmp.data[0]);
You are pushing once more the same reference to variable in an array.
Just create new variable before you assign values to it and before you push it in the array.
Something like this:
var tmp = {};
tmp.company_id = neworganization.data.company_id;
tmp.company_name = neworganization.data.company_name;
tmp.branches=[];
console.log(tmp);
$scope.myorganizations.data.push(tmp);
FYI http returns promisse, you don't have to wrap it once more.

Related

Angularjs passing id into modal function()

I am using angularjs and spring mvc for my application. At first I am displaying all the placements with one button Placed Candidates. I am doing ng-repeat for displaying all the placements.
Here is my html.
<div class="row" data-ng-repeat="placement in placements">
<div class="col-xs-12 col-sm-12 col-md-12">
<h5>{{placement.companyName}}</h5>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<h6>{{placement.placementDate | date:'dd MMM yyyy'}}</h6>
Company Target (appox):10 Achieved:
</div>
<a href="javascript:void(0);" data-ng-
click="placedcandidatespopup(placement.placementId);">//here i can
get particular placementId but how to pass this id to
savePlacementStudents() method in controller.js???//
PlacedCandidates
</a>
</div>
I am calling one modal popup function. Here is controller.js
$scope.placedcandidatespopup = function()
{
AdminUsersService.getAllUsers().then(function(response)
{
$scope.allusers=response.data;
console.log($scope.allusers);
})
$(".placedcandidates").modal("show");
}
I am calling modal by name "placedcandidates".
Here is the modal
<div class="modal right fade placedcandidates" id="myModal1"
tabindex="-1" role="dialog" aria-labelledby="myModalLabel2">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6" data-ng-
repeat="student in allusers">
<input id="{{student.studentId}}" type="checkbox" value="
{{student.studentId}}" data-ng-
checked="selection.indexOf(student.studentId) >-1"
data-ng-click="toggleSelection(student.studentId)"/>
<label for="{{student.studentId}}"></label>
{{student.firstName}}
</div>
</div>
</div>
<div class="modal-footer" style="position: fixed;">
<input type="button" value="Submit" class="btn" data-ng-
click="savePlacementStudents()">
</div>
</div>
</div>
</div>
After clicking on button popup modal will display with all Students with checkboxes placed beside them.Now I am able to save studentId into database.But I am not able to pass placementId for saving.
Here is my savePlacementStudents method in controller.js.
$scope.selectedStudents = {};
$scope.savePlacementStudents = function(selectedStudents)
{
selectedStudents.selectedList = $scope.selection;
AdminPlacementService.savePlacementStudents(selectedStudents).then
(function(response)
{
if(response.data=="success"){
$window.scrollTo(0,0);
$scope.selectedStudents = {};
$scope.getplacementdetails($scope.currentPageIndex);
$scope.successmessage="Student Selection Saved!;
$timeout(function() {
$scope.successmessage="";
$scope.closeplacedcandidatespopup();
}, 1500);
}
});
}
Can anyone tell how can I pass respective placementId to this saveStudents method() so that I can set that placementId for those students selected.
Here is the solution.
The placementId passed to function placedcandidatespopup can be saved as follows in function placedcandidatespopup
$scope.selectedPlacementId = placementId;
Now the same $scope will have access in Popup also as it is using same controller.js. And now you can use this $scope.selectedPlacementId anywhere in controller.js
So you don't need to pass placementId...!!
Hope that would help you..!!
$scope.placedcandidatespopup = function(id)
{
AdminUsersService.getAllUsers().then(function(response)
{
$scope.allusers=response.data;
console.log($scope.allusers);
})
$scope.inserted = {
placementId:id,
};
var modalInstance = $uibModal.open({
templateUrl: 'views/test/myModal1.html',
controller: 'TestCntrl',
size: "Modelwidth",
resolve: {
items: function () {
return $scope.inserted;
}
}
});
}
In model you have to access using items.placementId and when you savePlacementStudents() method send placementId as well with student info.

how to access nested json element in angular js

**I want to display seeds or any other data present in "torrents" in html using angular **
This code works fine but when i try to display seeds it displays nothing.
HTML CODE
<section class="list">
<article ng-repeat="object in yifito">
<a href="{{object.url}}" target="_system" onclick="window.open('{{object.url}}',_system,'location=yes')" class="item">
<img ng-src="{{object.small_cover_image}}">
<h2 class="noWhiteSpace">{{object.title}}</h2>
<p class="noWhiteSpace">{{object.genres}}</p>
<p class="noWhiteSpace">Year {{object.year}} Rating {{object.rating}}</p>
<p class="noWhiteSpace">{{object.movies.seeds}}</p>
</a>
</article>
</section>
angular Code
var app = angular.module('browser', ['ionic']);
app.controller('controller',function($scope,$http){
$scope.br =[]owse;
$http({
method: "GET",
url:
})
.then(function(toData){
$scope.to= toData.data.data.movies;
console.log(data);
})
})
[1]:
Your seeds field is inside torrents. The field torrents is a list.
So, to display data from torrents, you must use a loop.
<article ng-repeat="object in yifito">
<a href="{{object.url}}" target="_system" onclick="window.open('{{object.url}}',_system,'location=yes')" class="item">
<img ng-src="{{object.small_cover_image}}">
<h2 class="noWhiteSpace">{{object.title}}</h2>
<p class="noWhiteSpace">{{object.genres}}</p>
<p class="noWhiteSpace">Year {{object.year}} Rating {{object.rating}}</p>
<div ng-repeat="torrent in object.torrents">
<p class="noWhiteSpace">{{torrent.seeds}}</p>
</div>
</a>
</article>
It will display seeds for each torrent of your movie.
Simply access seeds by modifiying your code to :
<p class="noWhiteSpace">{{object.seeds}}</p>
This is because the structure of your object $scope.yifito is as follows:
[
{title: abc,
genere: afsdf,
year: 2016,
rating: 8,
seeds: 234},
{...}
]
Some observations :
seeds property is inside the object of a torrent array.
DEMO
var app = angular.module('myApp', []);
app.controller('MyCtrl',function($scope,$http){
$scope.yifito =[];
$http({
method: "GET",
url: "https://yts.ag/api/v2/list_movies.json?limit=50"
})
.then(function(yifitoData){
$scope.yifito = yifitoData.data.data.movies;
console.log($scope.yifito);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="object in yifito">
<a href="{{object.url}}" target="_system" onclick="window.open('{{object.url}}',_system,'location=yes')" class="item">
<img ng-src="{{object.small_cover_image}}">
<h2 class="noWhiteSpace">{{object.title}}</h2>
<p class="noWhiteSpace">{{object.genres}}</p>
<p class="noWhiteSpace">Year {{object.year}} Rating {{object.rating}</p>
<div ng-repeat="item in object.torrents">
<p class="noWhiteSpace">{{item.seeds}}</p>
</div>
</a>
</div>
</div>

How to add text box runtime and insert its value to db in angularjs

I want to create Curd app using AngularJS & MVC.
In that I am able to add, update and delete particular data from grid, but there is one task where I am getting stuck.
Here what I need to do is, I should be able to add multiple run time text box on that insert page to take any no of input from user, so I don't know how to do it and how to add those run time added text box values in DB.
It would be much appreciated if you help me on this.
Try this,
Here is the working fiddle
<div ng-controller="MyCtrl">
<div class="row" ng-repeat="(key,val) in data">
<div class="col-md-12">
<input type="text" ng-model="val.text">
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-primary" ng-click="addTextbox()">
Add Textbox
</button>
</div>
<div class="col-md-12">
<button class="btn btn-success" ng-click="sendDataToServer()">
Send Data
</button>
</div>
</div>
<div class="row">
<div class="col-md-12">
Result = {{data}}
</div>
</div>
</div>
Controller's code
var myApp = angular.module('myApp',[]);
function MyCtrl($scope,$http) {
$scope.data = [];
$scope.addTextbox = function(){
$scope.data.push({'text':''});
}
$scope.sendDataToServer = function(){
console.log(JSON.stringify($scope.data));
$http({
url: 'your_server_url',
method: "POST",
data: JSON.stringify($scope.data),
headers: {
'Content-Type': undefined
}
}).then(function(res) {
// do stuff on success
}, function(errorMsg) {
console.log(errorMsg);
// showing error
});
}
}
Here you will get all textbox's data into $scope.data, Now you can send this data by clicking Send Data button.
Provide the url where you want to submit this data.
Comment if you have any issue.

Repeating the nested objects of a single element with angular

Most of the answers I've found are for repeating the entire object, and that works for me without problem. What I need is to display the objects of an element in an array. Here is my controller:
var app = angular.module('QLoad', []);
app.controller('loadCtrl', function($scope) {
$scope.question=[
{Id:'1', qText:'What\'s your Gender?',aCollection:[
{text:'Male',
icon:'fa fa-male fa-5x'},
{text:'Female',
icon:"fa fa-female fa-5x"}
]
},
{Id:'2', qText:'What kind of Pain do you have?',aCollection:[
{text:'Burning',
icon:'fa fa-fire fa-5x'},
{text:'Stinging',
icon:"fa-bee.png"}
]
}];
});
As I mentioned, I could easily do two nested ng-repeats and display everything, but I only need to display the answers for each individual question. That's why I have the following two views I've tried, but it neither works:
<h1>{{question[0].qText}}</h1>
<div ng-repeat="q in question">
<div ng-repeat="answer in q.aCollection" class="content">
<div class=button>
<i class="{{q[0].answer.icon}}" aria-hidden="true"></i>
{{q[0].answer.text}}
</div>
</div></div>
Nor does this work:
<h1>{{question[0].qText}}</h1>
<div ng-repeat="answer in question[0].aCollection" class="content">
<div class=button>
<i class="{{answer.icon}}" aria-hidden="true"></i>
{{answer.text}}
</div>
</div></div>
And this is where I'm stuck. I can't display a single question object and its nested array. Thank you for your help.
You can use [limitTo][1] filter to achieve that.
<div ng-repeat="q in question | limitTo:1">
<div ng-repeat="answer in q.aCollection" class="content">
<div class=button>
<i class="{{answer.icon}}" aria-hidden="true"></i>
{{answer.text}}
</div>
</div></div>
You can define an index which will be incremented with the ng-click.
Template
<h1>{{question[questionTrackIndex].qText}}</h1>
<div ng-repeat="answer in question[questionTrackIndex].aCollection" class="content">
<div class=button>
<i class="{{answer.icon}}" aria-hidden="true"></i>
{{answer.text}}
</div>
</div>
<div class="btn btn-warning" ng-if="questionTrackIndex != 0" ng-click="previousQuestion()">Previous</div>
<div class="btn btn-warning" ng-if="question.length - 1 > questionTrackIndex" ng-click="nextQuestion()">Next</div>
Controller
$scope.questionTrackIndex = 0;
$scope.question=[
{Id:'1', qText:'What\'s your Gender?',aCollection:[
{text:'Male',
icon:'fa fa-male fa-5x'},
{text:'Female',
icon:"fa fa-female fa-5x"}
]
},
{Id:'2', qText:'What kind of Pain do you have?',aCollection:[
{text:'Burning',
icon:'fa fa-fire fa-5x'},
{text:'Stinging',
icon:"fa-bee.png"}
]
},
{Id:'3', qText:'Question no 3',aCollection:[
{text:'Answer1',
icon:'fa fa-fire fa-5x'},
{text:'Answer2',
icon:"fa-bee.png"}
]
}
];
$scope.nextQuestion = function() {
$scope.questionTrackIndex++;
}
$scope.previousQuestion = function() {
$scope.questionTrackIndex--;
}
The variable $scope.questionTrackIndex has been used to scroll through the questions. I have added two buttons next and previous to scroll through the questions. With clicking next button, $scope.questionTrackIndex has been incremented and with clicking previous button, $scope.questionTrackIndex has been decremented.
See this PLUNKER
One of solution maybe is
<div ng-repeat="q in question">
<div ng-click="a($index)">{{q.qText}}</div>
</div>
<h1>{{answ.text}}</h1>
<div ng-repeat="answer in answ.answerList" class="content">
<div class=button>
<i class="{{answer.icon}}" aria-hidden="true"></i>
{{answer.text}}
</div>
and your controller look like
$scope.answ = {};
$scope.answ.text = $scope.question[0].qText
$scope.answ.answerList = $scope.question[0].aCollection;
$scope.a = function(index){
$scope.answ.text = $scope.question[index].qText
$scope.answ.answerList = $scope.question[index].aCollection;
}
Example you can see on link

AngularJs how to reload a template page after selecting a charater

I am using http.get and i need to reload a template after selecting a character so that my template gives the answer according to what I selected
The code of the template
<div class="container-fluid" ng-controller="CriterioCtrl">
<div id="result"></div>
<div>
Selected Items:
<div ng-repeat="id in selection">
{{id}}
</div>
</div>
<div ng-repeat-start="crit in data" class="row">
<h2 align="center">{{crit.name}}</h2>
<div ng-repeat="caracter in crit.characters" class="col-md-4">
<div type="checkbox" value="{{caracter.id}}" ng-checked="selection.indexOf(caracter.id) > -1" ng-click="clickSelection(caracter.id)">
<a href="#crit" class="thumbnail" ng-click="clickCriterios(caracter.id)">
<h4 align="center">{{caracter.name}}</h4>
<img ng-src="http://skaphandrus.com/{{caracter.image_url}}"/>
</a>
</div>
</div>
</div>
<div ng-repeat-end>
</div>
<!--<button class="btn" ng-click="toggle()">Toggle</button>
<p ng-show="visible">Hello World!</p> codigo de um botao -->
</div>
This code is for the selection
$scope.selection=[];
$scope.clickSelection = function clickSelection(caracterId) {
var idx = $scope.selection.indexOf(caracterId);
// is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// is newly selected
else {
$scope.selection.push(caracterId);
}
var selectedId = $scope.selection;
console.log(selectedId);
// Check browser support
if (typeof(Storage) != "undefined") {
// Store
localStorage.setItem("idSelect", selectedId);
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("idSelect");
}
};
This code is the http part in another controller
MyApp.controller('EspeciesCtrl', function ($scope, $http) {
$http({
url: 'someurl',
method: "post",
params: {module_id: localStorage.getItem("idMod"),"characters[]": [localStorage.getItem("idSelect")]}
})
.then(function(res){
$scope.data = res.data;
});
});
This is the code of the template that have to change after the selection
<div class="container-fluid" ng-controller="EspeciesCtrl">
<div class="row">
<div ng-repeat="esp in data" class="col-md-6">
<a href="#infEsp" class="thumbnail" ng-click="clickEspecie(esp.id)">
<h4 align="center">{{esp.name}}</h4>
<img ng-src="{{esp.image_src}}"/>
</a>
</div>
</div>
</div>
How can i do that?
edit 1
If I've correctly understood, you may need to use ng-show (https://docs.angularjs.org/api/ng/directive/ngShow) whose boolean value checks if the user selected anything and show the extra bit of code you need, instead of trying to have another http request.
Also, it seems like you are using $scope.data for both the esp and the crit, so you will end up with the errors.
You probably don't need to reload the template.
You may want to use the data in $scope.data inside the template in order to let Angular manage the update on the view. As soon as the $scope.data changes, the rendered HTML changes too.
I can't comment but it would be helpful if you could share the template you are using and be more specific in your request :)

Resources