ng:repeat not loading data - javascript

This is my controller function to get data from server.
function carsController($http, $scope, $timeout) {
var vm = this;
vm.getCarData = getCarData;
function getCarData(){
$http.get('/api/getData').then(function (response) {
console.log(response.data.message);
vm.list = response.data.message;
});
}
}
Here is the data returned.
{
"message":[
{
"emp_id":1,
"emp_name":"toyota",
"city":"city1",
"nic_no":4554
},
{
"emp_id":2,
"emp_name":"sunny",
"city":"city2",
"nic_no":57412
},
{
"emp_id":3,
"emp_name":"tata",
"city":"city3",
"nic_no":1234
}
]
}
and html code to show data. I am using carsController as cars
<div class="row" data-ng-init="cars.getCarData()">
<div class="panel panel-default">
<table class="table table-bordered table-hover">
<tr>
<th>Name</th>
<th>Pages</th>
</tr>
<tr ng:repeat="vehicle in cars.list track by $index">
<td>{{vehicle.emp_name}}</td>
<td>{{vehicle.city}}</td>
</tr>
</table>
</div>
</div>
instead of showing data, UI show 100+ empty rows when page loaded.
What could be the issue?
UPDATED
If I manually set value as below, This works well.
vm.list = [
{
"emp_id":1,
"emp_name":"toyota",
"city":"city1",
"nic_no":4554
},
{
"emp_id":2,
"emp_name":"sunny",
"city":"city2",
"nic_no":57412
},
{
"emp_id":3,
"emp_name":"tata",
"city":"city3",
"nic_no":1234
}
];

the issue is, as you can see in the console log you have posted, response.data.message is an object. Not an array.
Try this instead
vm.list = response.data.message.message;
The following will bind the message array

You have two problems.
You are assigning vm.list to response.data.message, which, as NJ_93 points out, is an object. Use
vm.list = response.data.message.message;
You're not calling your getCarData() function from your controller. So the data is never fetched.

Are you sure that the problem is not because of you have used two different objects. vm.list for receiving the data from $http and using cars.list for ng-repeat
store data to $scope.vm.list
and in the UI use ng-repeat="cars in vm.list track by $index"

Related

How to stop inner ng-repeat in a nested loop from updating when the array changes

So I have an array of events and each event has teams participating. these two object are related but neither is a property of the other.
What I want to do is loop through every event and display every team participating in it. I try to do this using nested ng-repeats. My problem is the inner ng-repeats only displays once the outer ng-repeat has finished executing. Meaning that what ever team participated in the last event processed will be displayed in every table.
In my controller I have an array of teams and I update that array every time I get a new event, and an array of every
here is my repeating table
<div ng-repeat="event in events" ng-init="getTeams(event.eventId)">
<div class="active title">Teams in {{event.eventName}} #{{event.eventId}}</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Sport</th>
<th>Motto</th>
<th>W-L-D</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="team in teams">
<td>{{team.teamName}}</td>
<td>{{team.teamSport}}</td>
<td>{{team.teamMotto}}</td>
<td>{{team.win}}- {{team.lose}} - {{team.draw}}</td>
<td>{{team.teamDescription}}</td>
</tr>
</tbody>
</table>
</div>
and here is my controller
(function(){
angular
.module('foo')
.controller('EventController', function ($scope, $location, EventService) {
$scope.events = [];
$scope.targetEvent = {};
$scope.teams = [];
EventService.getEvents()
.then(function(events){
$scope.events = events;
});
$scope.getTeams = function(currEventId){
EventService.getTeams(currEventId)
.then(function(eventTeams) {
$scope.teams = eventTeams;
})
}
})()
I have tried using track by but tracking it by the eventId or teamId does not seem to work. Thank you in advance for your help
Although you have creating teams variable each time. It would be global and single for all events as per your current implementation. I don't think so you should be using ng-init here, rather perform that operation inside controller itself by looping over events.
EventService.getEvents().then(function(events){
$scope.events = events;
//loop over each event.
events.forEach(function(event){
EventService.getTeams(currEventId)
.then(function(eventTeams) {
//placed specific teams on event level
event.teams = eventTeams;
})
})
});
Then you just need to change the inner ng-repeat to below and remove ng-init
<tr ng-repeat="team in event.teams">

Accessing data in a strangely formatted JSON file in JavaScript

I was given the following JSON format and I am having a difficult time getting to the information. I want to put it into a data table.
"data": {
"HeadingOne":{
"Columns":["Row1", "Row2"],
"Data":[["firstData", "secondData"]]
}
}
I am told that I should be able to access this data but I have absolutely no clue how to get to "firstData" in datatables. (from datatables.net) This is what I have tried
$(document).ready(function() {
$('#example').dataTable( {
"ajax": "<%= request.getContextPath()%>/ajax/mastermenu.txt",
"columns":[
{"data": "HeadingOne.Data.Row1"}
]
} );
} );
HTML:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Row1</th>
<th>Row2</th>
</tr>
</thead>
</table>
As others have noted, you're missing a } at the end. After you fix that this should work.
Assuming the object is called data, this will get you "firstData"
console.log(data.HeadingOne.Data[0][0]); // "firstData"
Yeuch. But:
var data = {
"HeadingOne":{
"Columns":["Row1", "Row2"],
"Data":[
["firstData", "secondData"]
]
}
}
var firstData = data['HeadingOne']['Data'][0][0]
Note: I had to add a final } to that block otherwise it was not valid
If you're trying to access firstData by name, hopefully it's obvious that it won't work as it's contained in an array within an array (hence the [0][0]).

Angularjs ng-repeat doesn't update when the model changes

I Have this code in my project. I try to add data from database using $http, but ng-repeat doesn't update de table, only shows a blank row.
When I check the scope, data is already there.
I've read many answers but they does not seem to be related to my problem.
<div ng-controller="TweetsController">
<table class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th class="col-md-5"><i class="fa fa-fw fa-twitter text-muted hidden-md hidden-sm hidden-xs"></i> Texto</th>
<th class="col-md-1 text-center"> Lista</th>
<th class="col-md-1 text-center"> Cuenta</th>
<th class="col-md-1 text-center"> Red</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tuit in filtrado">
<td>{{tuit.texto}}</td>
<td class="text-center">{{tuit.lista.nombre}}</td>
<td class="text-center">{{tuit.lista.cuenta.nombre}}</td>
<td class="text-center">{{tuit.lista.cuenta.red.tipo}}</td>
</tr>
</tbody>
</table>
<div>
<pagination total-items="ufilter.length" itemsPerPage="itemsPerPage" ng-model="currentPage"></pagination>
</div>
</div>
Controller:
.controller('TweetsController', ['$scope','$http','filterFilter', function($scope,$http,filterFilter) {
$scope.currentPage = 1;
$scope.itemsPerPage = 10;
$scope.filtrado = [];
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
};
// retrieve tweets
$http.get('admin/twitter').success(function(tweets) {
$scope.tweets = tweets;
});
$scope.saveTweet = function(isValid) {
if(isValid) {
var tuit = {
texto: $scope.texto,
lista_id: $scope.lista
};
$http.post('admin/twitter', tuit).success(function(t) {
$scope.tweets.push(t);
});
}
};
$scope.filtrar = function(filtro) {
if($scope.tweets != undefined) {
$scope.ufilter = filterFilter(filtro, $scope.buscar);
var inicio = ($scope.currentPage - 1) * $scope.itemsPerPage;
var fin = inicio + $scope.itemsPerPage;
$scope.filtrado = $scope.ufilter.slice(inicio, fin);
}
};
$scope.$watch('tweets', function() {
$scope.filtrar($scope.tweets);
});
$scope.$watch('currentPage', function() {
$scope.filtrar($scope.tweets);
});
$scope.$watch('buscar', function() {
$scope.filtrar($scope.tweets);
$scope.setPage(1);
});
}])
EDIT:
I Solved it!
The problem is the way how the retrieve data is wrapped
$scope.tweets.push(t[0])
You need to apply to the scope
$http.get('admin/twitter').success(function(tweets) {
$scope.tweets = tweets;
$scope.$apply()
});
This is a great blog post that explains it:
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
The reason why your ng-repeat is not updating after the $http request is due to the $http is async and your javascript turn for the controller has finished before the response is back from your $http request. So you must notify the scope that things have changed and push it to the scope.
The problem is the way how the retrieve data is wrapped
instead of this:
$http.post('admin/twitter', tuit).success(function(t) {
$scope.tweets.push(t);
});
this:
$http.post('admin/twitter', tuit).success(function(t) {
$scope.tweets.push(t[0]);
});
There is the easy way and the correct way.
This is the easy way
//Utility Functions
function Digest($scope) {
//this may not be future proof, if it isn't then you may have to try $timeout(function(){//do something})
if (!$scope.$$phase) {
try {
//using digest over apply, because apply fires at root, and I generally don't need root.
$scope.$digest();
}
catch (e) { }
}
//console.log('$scope snapshot:', $scope);
}
In your code use this by calling
$http.post('admin/twitter', tuit).success(function(t) {
Digest($scope.tweets.push(t));
});
This is the correct way.
https://docs.angularjs.org/api/ng/service/$q
Have your HTTP call wrapped in a $q promise. Then when it is either succeed or error, then fulfill the promise. The repeater will honor the promise.
For anyone else who may run into this issue where the UI just isn't updating - even after doing an $apply or sticking within a $timeout. I've just realised I made a stupid mistake and had added :: to the embedded property and forgotten about it.
So I had my ng-repeat and inside I had a {{ ::item.name }}. For those of you who don't know what the :: does; it tells angular to set the data and not set any additional watches, which in turn then stops angular trying to update that property. This is useful for data that you know won't ever change. See the below link for more information on one time bindings:
http://blog.thoughtram.io/angularjs/2014/10/14/exploring-angular-1.3-one-time-bindings.html
So my solution was just to remove the :: so: {{ ::item.name }} became {{ item.name }}

AngularJs. Problems with ng-repeat

I'm having two tables witch renders data trough angularJs, coming from 2 c#-methods.
The tables are structured almost exactly the same. The first one below is used as I searchfield and the other one is used basiclly to render names.
My problem is that the first one works perfect, but the other one does not. And I don't see the problem. Any help would be appreciated. // Thanks!
Here are my two tables. (the first one is working)
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular.min.js"></script>
<div ng-app="searchApp">
<div ng-controller="searchController">
#*first table works*#
<span style="color: white">Search:</span> <input data-ng-click="myFunction()" ng-model="searchText">
<table style="color: white" id="searchTextResults">
<tr><th>Name</th></tr>
<tr ng-show="!!searchText.length != 0" ng-repeat="friend in friends | filter:searchText">
<td data-id="{{friend.id}}" data-ng-click="SendFriendRequest(friend.id)">{{friend.id.replace("RavenUsers/","")}}</td>
</tr>
</table>
#*Does not work*#
<input type="button" value="Get friends requests" data-ng-click="GetFriendRequests()">
<table style="color: white">
<tr><th>Friend requests</th></tr>
<tr ng-repeat="friendRequest in friendRequests">
<td data-id="{{friendRequest.UserWhoWantsToAddYou}}" data-ng-click="acceptUserRequest(friendRequest.UserWhoWantsToAddYou)">{{friendRequest.UserWhoWantsToAddYou}}</td>
</tr>
</table>
</div>
</div>
HERE IS MY SCRIPT
<script>
var App = angular.module('searchApp', []);
App.controller('searchController', function ($scope, $http) {
//Get all users to the seachFunction
$scope.myFunction = function () {
var result = $http.get("/Home/GetAllUsersExeptCurrentUser");
result.success(function (data) {
$scope.friends = data;
});
};
//Get friendRequests from other users
$scope.GetFriendRequests = function () {
var result = $http.get("/Home/GetFriendRequests");
result.success(function (data) {
$scope.friendRequests = data;
});
};
});
</script>
The first script-function called myFunction works perfect and the data coming from my c#-method looks like this:
[{"id":"RavenUsers/One"},{"id":"RavenUsers/Two"},{"id":"RavenUsers/Three"}]
The second script-function called GetFriendRequests does not work, and as far as I can see there is no difference between this data passed into here than the data passed into myFunction:
[{"userWhoWantsToAddYou":"RavenUsers/Ten"},{"userWhoWantsToAddYou":"RavenUsers/Eleven"}]
I'd suggest you use then instead of success because $http returns a promise.
If your table doesn't "render" then put a breakpoint inside success function, console.log() the data or check friendRequests inside your HTML template, e.g. using <div>{{ friendRequests | json }}</div>, to ensure you actually got data from response.
Now you do not handle exceptions at all.
Example:
result.then(function(data) {
console.log('got data')
},function(error) {
console.log('oh noes :( !');
});
Related plunker here http://plnkr.co/edit/KzY8A3
It would be helpful if you either (a) provided a plunker to your code or (b) provided the error message.
ng-repeat requires a uniquificator on each item in the repeat, which defaults to item.id. If you don't have an id field on the item, you'll need to tell angular what field to use.
https://docs.angularjs.org/api/ng/directive/ngRepeat
So I'd suggest changing
<tr ng-repeat="friendRequest in friendRequests">
to
<tr ng-repeat="friendRequest in friendRequests track by userWhoWantsToAddYou">
and see if that works.

How to pass javascript array variable values to html using angular.js

I am new to angular.js
I want to create a table by populating values from a javascript array variable.
I created and entered values in my variable like this
var result=[];
//some loop. Just demonstrating that there are multiple values of id and text
result.push(
{
"id":obj["id"],
"text":obj["text"],
}
);
I want a new row for each id and text from result variable in html
<table>
<tr><td>id</td><td>text</td></tr>
<table>
What is way to do this using angular.js.
Figured it out. Putting it here if anyone needs it.
Javascript code:
function controller($scope, $http) {
$scope.results=[];
$http.get(url).success(function (data) {
$.each(data, function () {
var obj = data;
console.log(obj);
$scope.results.push(
{
"id": obj["obj_id"],
"text": obj["text"]
}
);
});
});
}
html code
<div ng-controller="controller">
<table ng-repeat="result in results">
<tr><td>{{result.id}}</td><td>{{result.text}}</td></tr>
<table>
</div>

Categories