AngularJS - Nested ng-repeat using two objects - javascript

Controller:
$scope.init = function(team){
$http.get("/getLeaderByTeamID/"+team.id)
.success(function (data, status, headers, config) {
// this is the object that I need to list in the table
$scope.leader = data;
})
.error(function (data, status, header, config) {
$log.error("Error!");
});
}
The data-ng-repeat directives in the table:
<table>
<thead>
<tr>
<th>Team</th>
<th>Leader</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="team in teams" data-ng-init="init(team)">
<td>{{team.name}}</td>
<td data-ng-repeat="l in leader">{{l.name}}</td>
</tr>
</tbody>
The logic is as follow:
When every team is listed the init() function will send the object to the controller.
In the other side the init() function will make a query with the ID team in order to get its respective leader.
The function will return one object and the second ng-repeat directive will list this into its respective team object.
But as I showed the list is wrong because one same object is listed in every team.
I was thinking create an array into the init() function with every object but I don't know how to concatenate every object in order to create an array.
Any suggestions?

I think you'r just updating $scope.leader value in every request ,so at the end $scope.leader will have the same value for all teams. try this.
$scope.init = function(teamId){
$http.get("/getLeaderByTeamID/"+teamId)
.success(function (data, status, headers, config) {
// this is the object that I need to list in the table
$scope.leader[teamId] = data;
})
.error(function (data, status, header, config) {
$log.error("Error!");
});
<table>
<thead>
<tr>
<th>Team</th>
<th>Leader</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="team in teams" data-ng-init="init(team.id)">
<td>{{team.name}}</td>
<td data-ng-repeat="l in leader[team.id]">{{l.name}}</td>
</tr>
</tbody>
or you can use function return leaders array in the second ng-repeat like:
<td data-ng-repeat="l in getLeader(team.id)">{{l.name}}</td>

Related

Angularjs Smart table not working for Dynamic data

I have a situation where i am using angularJs smart table for filtering.
html:
<section class="main" ng-init="listAllWorkOrderData()">
<table st-table="listWorkOrderResponse">
<thead>
<tr>
<th st-sort="id">ID <i></i></th>
<th st-sort="project">Project <i></i></th>
</tr>
</thead>
<tbody ng-repeat="workOrder in listWorkOrderResponse">
<tr>
<td>{{workOrder.id}}</td>
<td>{{workOrder.project}}</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
</section>
I am testing for 2 different cases.
In my controller first i call the same function but send dummy array and in the second case i send the array received from the api call.
1. Dummy data
$scope.listAllWorkOrderData = function () {
var listWorkOrderResponse = [{"id":"1","project":"project1"},{"id":2,"project":"project2"},{"id":"3","project":"project3"}];
}
2. I am using a service and fetching data through api.
$scope.listAllWorkOrderData = function () {
TestService.listAllWorkOrderData().then(function (response, status, headers, config) {
if (response != undefined && response != null) {
if (!$scope.listWorkOrderResponse) {
$scope.listWorkOrderResponse = [];
}
$scope.listWorkOrderResponse = response;
}, function (response, status, headers, config) {
console.log(response);
});
When i am using case1 the sorting works fine.
But when i use case2 the sorting does not work. Onclick of it the data just disappears.
I tried debugging to see whether the listAllWorkOrderData function is being called again when we click on the filter.But it is just called once when the page is loaded to populate the table.So that means the data is present in the listWorkOrderResponse. Then why is it not sorting?
I checked the response for both the situation by printing them the only difference i found was that the listWorkOrderResponse which comes from the api call has a $$hashKey: "object:363" added to it.
Can anyone point me what mistake i am doing.
I was able to resolve this issue by using stSafeSrc attribute
In the controller we add
$scope.listAllWorkOrderData = function () {
TestService.listAllWorkOrderData().then(function (response, status, headers, config) {
if (response != undefined && response != null) {
if (!$scope.listWorkOrderResponse) {
$scope.listWorkOrderResponse = [];
}
$scope.listWorkOrderResponse = response;
// we add one more list.
$scope.displayedWOList = [].concat($scope.listWorkOrderResponse);
}, function (response, status, headers, config) {
console.log(response);
});
and then in the html table we add the stSafeSrc attribute.
stSafeSrc attribute from the Smart Table document
http://lorenzofox3.github.io/smart-table-website/
stSafeSrc attribute
If you are bringing in data asynchronously (from a
remote database, restful endpoint, ajax call, etc) you must use the
stSafeSrc attribute. You must use a seperate collection for both the
base and safe collections or you may end up with an infinite loop.
<section class="main" ng-init="listAllWorkOrderData()">
<table st-table="displayedWOList" st-safe-src="listWorkOrderResponse">
<thead>
<tr>
<th st-sort="id">ID <i></i></th>
<th st-sort="project">Project <i></i></th>
</tr>
</thead>
<tbody ng-repeat="workOrder in displayedWOList">
<tr>
<td>{{workOrder.id}}</td>
<td>{{workOrder.project}}</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
</section>
Why it is not working i don't know but yo can solve it by doing like below
repeat your response & create a new object & push it into an array..
var res = [];
for(var i=0; i<response.length; i++) {
var x = {"id":response[i].id, "project":response[i].project};
arr[i] = angular.copy(x);
}

Knockout.js: Updating objects loaded with mapping plugin

I want to render a table containing a list of objects my server is sending me. I'm currently doing this:
<table>
<thead>
<tr>
<th>id</th>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody data-bind="foreach: services">
<tr>
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
<td data-bind="text: status"></td>
</tr>
</tbody>
</table>
And the Knockout.js binding part:
var mappedData = komapping.fromJSON('{{{ services }}}');
ko.applyBindings({services: mappedData});
services is a variable containing JSON data and the whole page is rendered with handlebars. So far so good. I'm able to render the data received in the table.
Now the problem: I'd like to receive a notification which tells me that the status of a service has changed, and update the corresponding object within mappedData. The problem is that mappedData seems pretty opaque and I'm unable to retrieve an object and update it given its id.
Help appreciated!
Your mappedData variable at this point will be a knockout array with a bunch of objects that contain knockout observables.
So all you have to do is change the status observable in the correct object from the array.
function updateServiceStatus(id, status) {
var service = mappedData().filter(function(e) { return e.id() == id; });
if (service.length) {
service[0].status(status);
}
}
To get the object, you can write a helper function that will retrieve for you a service object. You could do something like this (assuming mappedData is an observableArray and id observable) :
function get_service_by_id(service_id){
for(var i=0;i<mappedData().length;i++){
if (mappedData()[i].id() === service_id){
return mappedData()[i];
}
}
return false;
}

Obtain data from Json using angular

Below is my code:
post.json
[
{
"client_id":"100",
"client_name":"MM Hope House",
"user_fname":"Betty",
"user_lname":"Johnson",
"user_id":"10",
"username":"bjohnson",
"total_web":"$500",
"campaigns":{
"campaign":[{
"id":"23",
"campaign_name":"MM Hope House",
"start_date":"4/15/2015",
"end_date":"6/13/2015",
"goal":"$20,000",
"total_pledges":"$1550",
"total_donations":"$1000"
}],
"pledgees":[{
"pledgee_fname":"Tavonia",
"pledgee_lname":"Evans",
"pledge_email":"tavonia#gmail.com",
"pledge_date":"4/22/2015",
"pledge_amount":"$50.00",
"paid":"$50.00",
"last_pledge":"$50.00"
}],
"donors":[{
"donor_fname":"Pat",
"donor_lname":"Smith",
"donor_email":"patsmith#onlinemediainteractive.com",
"total_cdonation":"$10.00",
"total_ldonation":"$450.00",
"last_donation":"$200.00",
"last_pledge":"$350.00"
}]
}
}
]
My HTML code:
<script>
function PostsCtrlAjax($scope, $http) {
$http({method: 'POST', url: 'assets/js/posts.json'})
.success(function(data) {
console.log(data);
$scope.posts = data;
})
.error(function(data, status) {
$scope.posts = data || "Request failed";
});
}
</script>
My HTML code where I want to populate data:
<thead>
<tr>
<th>Campaign ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Amount</th>
<th>Email ID.</th>
<th>Pledge Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="post in posts" >
<td>{{post.id}}</td>
<td>{{post.pledgee_fname}}</td>
<td>{{post.pledgee_lname}}</td>
<td>{{post.pledge_amount}}</td>
<td>{{post.pledge_email}}</td>
<td>{{post.pledge_date}}</td>
I am trying to get client_id pleg_fname from array, but do not know how to.
Your pledgess object is an array of objects so you should do this instead and your entire JSON is contained within an array so you need the first element which will be your entire object and you call it with posts[0] and then you specify the object you are trying to iterate : pledgees.
<tr ng-repeat="post in posts[0].campaigns.pledgees" >
<td>{{posts[0].campaigns.campaign[0].id}}</td>
<td>{{post.pledgee_fname}}</td>
<td>{{post.pledgee_lname}}</td>
<td>{{post.pledge_amount}}</td>
<td>{{post.pledge_email}}</td>
<td>{{post.pledge_date}}</td>
Edit
You're right, I totally missed that array. See this plunker where I tested it http://plnkr.co/edit/dvdnjv2mN2gljQGI9Lls?p=preview
Edit 2
If you want the campaign ID just add this (updated the original code with this change)
{{posts[0].campaigns.campaign[0].id}}
Because of your posts object contains an array of one element, you should use posts[0] to get the first (and the only one) element. Moreover, your pledgees array is inside a campaigns object, so posts[0] become posts[0].compaigns.pledgees.
You should try this :
<tr ng-repeat="post in posts[0].campaigns.pledgees" >
<td>{{post.id}}</td>
<td>{{post.pledgee_fname}}</td>
<td>{{post.pledgee_lname}}</td>
<td>{{post.pledge_amount}}</td>
<td>{{post.pledge_email}}</td>
<td>{{post.pledge_date}}</td>
</tr>
EDIT:
And, if you want the id from the campagin object at the same index than your pledgee item, you have to add track by $index to posts[0].campaigns.pledgees. So it's become posts[0].campaigns.pledgees track by $index.
So, now with $index you get the right index to get the right campaign ID in the campaign object with {{posts[0].campaigns.campaign[$index].id}}
And the result is :
<tr ng-repeat="post in posts[0].campaigns.pledgees track by $index" >
<td>{{posts[0].campaigns.campaign[$index].id}}</td>
<td>{{post.pledgee_fname}}</td>
<td>{{post.pledgee_lname}}</td>
<td>{{post.pledge_amount}}</td>
<td>{{post.pledge_email}}</td>
<td>{{post.pledge_date}}</td>
</tr>
You can see the result here : http://jsfiddle.net/Fieldset/y1asxm61/1/

Empty table rows with ng-repeat, AngularJS

I have input fields that you can submit, and the data that you entered is inserted into an database. This data is then looped out in a table with ng-repeat:
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Sträcka</th>
<th>Tid</th>
<th>Jämför</th>
</tr>
</thead>
<tr ng-repeat="info in test"><td>{{info.stracka}}</td><td>{{info.tid}}</td><td><input type="checkbox" id="{{info.id}}" class="checkboxfisk" ng-click="testa(info.id)"></tr>
</table>
The problem is that, When the database table is empty, and you are submiting data for the first time, 3 empty TR's rows are printed out, after you have hit submit. I used firebug to debug this, and the HTML look like this when I hover on the empty TR-rows:
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Sträcka</th>
<th>Tid</th>
<th>Jämför</th>
</tr>
</thead>
<tbody>
<tr class="ng-scope" ng-repeat="info in test">
<td class="ng-binding"></td>
<td class="ng-binding"></td>
<td>
<input id="" class="checkboxfisk" type="checkbox" ng-click="testa(info.id)">
</td>
</tr>
<tr class="ng-scope" ng-repeat="info in test">
<td class="ng-binding"></td>
<td class="ng-binding"></td>
<td>
</tr>
<tr class="ng-scope" ng-repeat="info in test">
<td class="ng-binding"></td>
<td class="ng-binding"></td>
<td>
</tr>
</tbody>
</table>
<form class="ng-pristine ng-invalid ng-invalid-required" novalidate="" ng-submit="submitForm(userForm.$valid)" name="userForm">
As you can see, there are td's with classname of ng-binding. What is this? Can anyone help me?
Here is my controller:
as.controller('Test', function($scope, $http, $rootScope, testFactory)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data.data;
});
$scope.form = {};
$scope.checkboxes = [];
$scope.testa = function(id) {
$scope.checkboxes.push(id);
};
$scope.submitForm = function(isValid) {
if(isValid)
{
$http.post($rootScope.appUrl + '/nao/test', $scope.form)
.success(function(data, status, headers, config) {
console.log(data);
console.log($scope.form);
}).error(function(data, status) {
});
}
};
});
EDIT: The problem was in my backend. I've have forgotten to add a parameter that is returned after that the mysql query is executed.
I see two possibilities.
In first, you should initialize your test scope variable before the $http call (to ensure it is initialized even if http request fails). And then create a method updateTest which will be called on succes of the submit form (to update test variable).
Your code should be like that:
as.controller('Test', function($scope, $http, $rootScope, testFactory)
{
// METHOD to update test items
updateTest = function() {
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data.data;
});
};
// init variables
$scope.form = {};
$scope.checkboxes = [];
$scope.test = [];
$scope.testa = function(id) {
$scope.checkboxes.push(id);
};
$scope.submitForm = function(isValid) {
if(isValid)
{
$http.post($rootScope.appUrl + '/nao/test', $scope.form)
.success(function(data, status, headers, config) {
console.log(data);
console.log($scope.form);
// update test item (to get back newly created one)
updateTest();
}).error(function(data, status) {
});
}
};
// first test items update
updateTest();
});

Ajax, json in AngularJS

I am trying to use the $http.get API to get a json data and then use it in my HTML tags.
I seem to miss something in the concept. here is my javascript:
var CouponsApp = angular.module('CouponsController', []);
CouponsApp.controller("CellCouponController", function($scope, $http){
$http.get('CouponsJSON.json').
success(function(data, status, headers, config) {
$scope.posts = data;
}).
error(function(data, status, headers, config) {
// log error
});
});
Here is my HTML:
<div id="CellTable" ng-controller="CouponController">
<p> Cell Phones Coupons</p>
<table border=1>
<tr>
<th>Model</th>
<th>Manufacturer</th>
<th>Cell Image</th>
<th>Manufacturer Url</th>
<th>Local Vendor</th>
<th>Local Vendor Address</th>
</tr>
<tr ng-repeat="coupon in coupons">
<td>{{CellPhones.model}}</td>
<td>{{CellPhones.manufacturer}}</td>
<td>
<img src="{{CellPhones.CellImage}}" alt="{{CellPhones.CellPhones}}" width="50px;" height="50px;" width="60px">
</td>
<td>
{{CellPhones.manufacturer}} URL
</td>
<td>{{CellPhones.localVendor}}</td>
<td>{{CellPhones.localVendorAddress}}</td>
</tr>
</table>
</div>
What is the correct way to get the json data, insert it to an object and then parse it in the ng-repeat?
You must define a $scope.coupons = {}; in your controller , and then attach your get data to that like this :
controller:
$scope.coupons = {};
$http.get('CouponsJSON.json')
.success(function(data){
// first console.log(data) it to check getting data is correctly working :
console.log(data);
$scope.coupons.coupon = data;
// its good practice to always use a DOT!!
})
Now in your html you can use ng-repeat like this :
<div ng-repeat="coup in coupons.coupon">
{{coup}}
</div>

Categories

Resources