ng-repeat not working angularjs 1.6 - javascript

This is my template for component gamesGrid which I am using in index.html. Inside of this template I have a table on which i want to use ng-repeat but it is not working.
<div class="container">
<table class="table table-hover">
<thead>
<tr>
<th>Title</th>
<th>Platform</th>
<th>Score</th>
<th>Genre</th>
<th>Editor's Choice</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="detail in gamesDetails">
<td>{{detail.title}}</td>
</tr>
</tbody>
</table>
</div>
This is my component.js file
(function() {
'use strict';
angular.module('myApp').component('gamesGrid', {
templateUrl: './components/games-grid.view.html',
controller:'gamesGridController'
});
})();
This is my controller.js file
angular.module('myApp').controller('gamesGridController',function(gridDataFactory) {
this.$onInit = function() {
};
this.$postLink = function() {
this.gamesDetails = [];
gridDataFactory.fetchUserDetails().then(function(response) {
this.gamesDetails = response;
console.log(this.gamesDetails);
});
}
});
And this is my factory:
angular.module('myApp').factory('gridDataFactory', function($http) {
var gameDetails = [];
var obj = {};
obj.fetchUserDetails = function(){
return $http.get('http://starlord.hackerearth.com/gamesarena').then(function(response) {
gameDetails = response.data;
gameDetails.shift();
return gameDetails;
});
}
return obj;
});
As you can see i have ng-repeat in my template but it is not working and i am not able to see any data on view.

You are using this.gamesDetails so change your View to use controller syntax as follows.
<div class="container" ng-controller="gamesGridController as ctrl">
<table class="table table-hover">
<thead>
<tr>
<th>Title</th>
<th>Platform</th>
<th>Score</th>
<th>Genre</th>
<th>Editor's Choice</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="detail in ctrl.gamesDetails">
<td>{{detail.title}}</td>
</tr>
</tbody>
</table>
</div>

this.$postLink = function() {
this.gamesDetails = [];
gridDataFactory.fetchUserDetails().then(function(response) {
$scope.gamesDetails = response;
console.log(this.gamesDetails);
});
}
In this piece of code i see you have assigned this.gameDetails, which is not available in the scope. Use $scope.gameDetails to bind it to the view.

Related

How to remove extra added row for generated JSON on button click either using AngularJS or JavaScript?

I am performing few operations like Add and Remove for my two JSON files data.
My requirement is that I need to add respective json names and show them in the table and then need to generate json object for the added/selected json names on button click. It's working fine(that I can able to show my json names on UI table and can get/generate the json data object for my selected/added json names data after button click).
But, the issue is: after generating the json object or after clicking of Send button, I can see that one row is adding extra on my UI table after clicking of Send button, I don't need this added extra row for my UI table, I need only whatever I added the json names only those should be displayed in my table after clicking of Send button. It's happening for my two json tables.(I have two Send buttons individually, one for First JSON and other for Second JSON).
I am not sure what's the wrong here ? Please help me that to display the selected json names in table on button click, that shouldn't include one extra row adding either using AngularJS or JavaScript. Thank you in advance ! Created Plnkr.
html:
<div>
<p>First Table:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Add</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key, value) in myFirstJson.Testing">
<td>{{getKey(value)}}</td>
<td><button ng-click="addFirst(value)">Add</button></td>
</tr>
</tbody>
</table>
<br> <br>
<table border="1" class="table">
<thead>
<tr>
<th>Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key, value) in firstJsonNames track by $index">
<td>{{getKey(value)}}</td>
<td><button ng-click="deleteFirst($index)">Delete</button></td>
</tr>
<tr ng-hide="firstJsonNames.length > 0">
<td colspan="3">
<p>No Names</p>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<table>
<tbody>
<tr>
<td>First Dropdown:<select ng-model="firstJsonNames.firstdropdown">
<option value="Test1">Test1</option>
<option value="Test2">Test2</option>
<option value="Test3">Test3</option>
</select><br />
</td>
</tr>
<tr>
<td>First Input:<input type="text" maxlength="50" size="50"
ng-model="firstJsonNames.firstInput" /> <br /></td>
</tr>
</tbody>
</table>
<br>
<br>
<button ng-click="generateFirstJson()">Send</button>
<br>
<br><p>Second Table:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Add</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key, value) in mySecondJson.MyTest">
<td>{{value.Main.static.name}}</td>
<td><button ng-click="addSecond(value.Main.static.name)">Add</button></td>
</tr>
</tbody>
</table>
<br>
<br>
<table border="1" class="table">
<thead>
<tr>
<th>Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="name in secondJsonNames">
<td>{{name}}</td>
<td><button ng-click="deleteSecond(name)">Delete</button></td>
</tr>
<tr ng-hide="mySecondJson.MyTest.length">
<td colspan="3">
<p>No Names</p>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<label>Enter Second Input Data:</label> <input
ng-model="secondJsonNames.SecondInput" placeholder="Input Text"><br>
<br>
<button ng-click="generateSecondJson()">Send</button>
<br>
<br>
</div>
app.js:
var app = angular.module('myApp', ['ui.router']);
app.controller('TestCtrl',function($scope, $http,$state,$stateParams,filterFilter,$rootScope) {
$rootScope.firstJsonNames = [];
$scope.secondJsonNames = [];
$scope.firstJsonNames.firstdropdown="Test1";
$scope.firstJsonNames.firstInput="1.5";
if($rootScope.myFirstJson == undefined)
{
$http.get('test.json').success(function(response) {
$rootScope.myFirstJson = response;
});
}
$scope.addFirst = function (name){
$rootScope.firstJsonNames.push(name);
console.log($rootScope.firstJsonNames);
};
$scope.deleteFirst = function (index){
$rootScope.firstJsonNames.splice(index,1);
};
$scope.getKey = function(item) {
return Object.keys(item)[0];
};
$scope.generateFirstJson = function(){
$rootScope.firstJsonNames.push({firstdropdown:$rootScope.firstJsonNames.firstdropdown, firstInput:$rootScope.firstJsonNames.firstInput});
console.log(angular.toJson($rootScope.firstJsonNames));
};
//second json
if($rootScope.mySecondJson == undefined)
{
$http.get('test1.json').success(function(response) {
$rootScope.mySecondJson = response;
});
}
$scope.addSecond = function (name){
$scope.secondJsonNames.push(name);
console.log($scope.secondJsonNames);
};
$scope.deleteSecond = function (name){
index = $scope.secondJsonNames.indexOf(name);
$scope.secondJsonNames.splice(index,1);
};
$scope.generateSecondJson = function(){
$scope.secondJsonNames.push({SecondInput:$scope.secondJsonNames.SecondInput});
console.log(angular.toJson($scope.secondJsonNames));
};
});
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'main.html',
controller: 'TestCtrl',
});
});
You are updating $rootScope.firstJsonNames and $scope.secondJsonNames, which are used in ng-repeat, So values are displaying in table. Use new variable for json creation.
For you are reference:
I have used
$scope.newjson2 = [];
$scope.newjson1 = [];
Plunker
http://plnkr.co/edit/r0VTaaT2rcfkiBNqyRmt?p=preview
JS:
var app = angular.module('myApp', ['ui.router']);
app.controller('TestCtrl',function($scope, $http,$state,$stateParams,filterFilter,$rootScope) {
$rootScope.firstJsonNames = [];
$scope.secondJsonNames = [];
$scope.firstJsonNames.firstdropdown="Test1";
$scope.firstJsonNames.firstInput="1.5";
$scope.newjson2 = [];
$scope.newjson1 = [];
if($rootScope.myFirstJson == undefined)
{
$http.get('test.json').success(function(response) {
$rootScope.myFirstJson = response;
});
}
$scope.addFirst = function (name){
$rootScope.firstJsonNames.push(name);
console.log($rootScope.firstJsonNames);
};
$scope.deleteFirst = function (index){
$rootScope.firstJsonNames.splice(index,1);
};
$scope.getKey = function(item) {
return Object.keys(item)[0];
};
$scope.generateFirstJson = function(){
$scope.newjson1 = angular.copy($rootScope.firstJsonNames);
$scope.newjson1.push({firstdropdown:$scope.firstJsonNames.firstdropdown, firstInput:$scope.firstJsonNames.firstInput});
console.log(angular.toJson( $scope.newjson1));
};
//second json
if($rootScope.mySecondJson == undefined)
{
$http.get('test1.json').success(function(response) {
$rootScope.mySecondJson = response;
});
}
$scope.addSecond = function (name){
$scope.secondJsonNames.push(name);
console.log($scope.secondJsonNames);
};
$scope.deleteSecond = function (name){
index = $scope.secondJsonNames.indexOf(name);
$scope.secondJsonNames.splice(index,1);
};
$scope.generateSecondJson = function(){
$scope.newjson2 = angular.copy($scope.secondJsonNames);
$scope.newjson2.push({SecondInput:$scope.secondJsonNames.SecondInput});
console.log(angular.toJson($scope.newjson2));
};
});
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'main.html',
controller: 'TestCtrl',
});
});

AngularJS search using filter not working

I am trying to search using angularjs filter method but its not working. I am not getting any errors in the console but still the search result is not showing up. Can someone help me on this.
This is my controller.js code:
.controller('SearchController',
[
'$scope',
'dataService',
'$location',
'$routeParams',
function ($scope, dataService, $location, $routeParams){
$scope.searchMovies = [ ];
$scope.searchCount = 0;
var getSearchResult = function (terms) {
dataService.getSearchResult(terms).then(
function (response) {
$scope.searchCount = response.rowCount + ' movies';
$scope.searchMovies = response.data;
$scope.showSuccessMessage = true;
$scope.successMessage = "All movie Success";
},
function (err){
$scope.status = 'Unable to load data ' + err;
}
); // end of getStudents().then
};
if ($routeParams && $routeParams.term) {
console.log($routeParams.term);
getSearchResult($routeParams.term);
}
}
]
);
This is the services.js code:
this.getSearchResult = function (terms) {
var defer = $q.defer(),
data = {
action: 'search',
term: terms
}
$http.get(urlBase, {params: data, cache: true}).
success(function(response){
defer.resolve({
data: response.ResultSet.Result,
rowCount: response.RowCount
});
}).
error(function(err){
defer.reject(err);
});
return defer.promise;
};
This is my app.js code:
. when('/search', {
templateUrl : 'js/partials/search.html',
controller : 'SearchController'
}).
This is the search.html code:
<div>
<label>Search: <input ng-model="searchMovie"></label><br><br><br><br>
</div>
<table class="table table-hover table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="search in searchMovies | filter:searchMovie">
<td>
{{search.title}}
</td>
<td>
{{search.description}}
</td>
<td>
{{search.name}}
</td>
</tr>
</tbody>
</table>
The search data is being retrieved from the database. I have tested the SQL and it works fine. Just thee problem is in the angularjs server side. Thank you.
You need to give Alias for controller in your app.js file
.when('/search', {
templateUrl : 'js/partials/search.html',
controller : 'SearchController'
controllerAs: 'movies',
});
Now After This in your search.html file pass controllerAs
<div>
<label>Search: <input ng-model="searchMovie"></label><br><br><br><br>
</div>
<table class="table table-hover table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="search in searchMovies | filter:searchMovie">
<td>
{{movies.search.title}}
</td>
<td>
{{movies.search.description}}
</td>
<td>
{{movies.search.name}}
</td>
</tr>
</tbody>

How can I use ng-switch to toggle displaying a nested table with AngularJS?

I'm trying to use ng-switch in AngularJS to expand a row in a table list to show another table (containing more details about that list item) when it's clicked.
However, I'm having trouble displaying the nested table. I've noticed that the problem only happens with nested tables. If I'm using ng-switch to expand a td instead of a table, it works as expected.
Here's a JSFiddle and my code to illustrate the problem: fiddle
The html:
<body ng-app="listAndDetails">
<div>
<table class="table table-bordered" ng-controller="ListAndOneDetailCtrl">
<thead>
<tr>
<th>Name</th>
<th>e-mail</th>
</tr>
</thead>
<tbody ng-repeat="user in users" ng-click="toggleSelected()" ng-switch on="isSelected(user)">
<tr>
<td>{{user.name}}</td>
<td>{{user.email}}</td>
</tr>
<tr ng-switch-when="true" class="light-gray">
<table>
<tr>
<td>Country</td>
<td>Address</td>
<td>Description</td>
</tr>
<tr>
<td>{{user.country}}</td>
<td>{{user.address}}</td>
<td>{{user.desc}}</td>
</tr>
</table>
</tr>
</tbody>
</table>
</div>
<div ng-controller="ListAndManyDetailsCtrl">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>e-mail</th>
</tr>
</thead>
<tbody ng-repeat="user in users" ng-controller="UserCtrl" ng-click="toggleSelected()" ng-switch on="isSelected()">
<tr>
<td>{{user.name}}</td>
<td>{{user.email}}</td>
</tr>
<tr ng-switch-when="true" class="light-gray">
<td>{{user.country}}</td>
<td>{{user.address}}</td>
<td>{{user.desc}}</td>
</tr>
</tbody>
</table>
</div>
</body>
The javascript:
angular.module('listAndDetails', [])
.value('users', [
{ name:'Damien', email:'damien#domain.com', desc:'Damien details go here...', country:'US', address:'address1'},
{ name:'Alex', email:'alex#domain.com', desc:'Alex details go here...', country:'UK', address:'address2'}
])
.controller('ListAndOneDetailCtrl', function ($scope, users) {
$scope.users = users;
$scope.selectUser = function (user) {
$scope.selectedUser = user;
};
$scope.isSelected = function (user) {
return $scope.selectedUser === user;
};
})
.controller('ListAndManyDetailsCtrl', function ($scope, users) {
$scope.users = users;
})
.controller('UserCtrl', function ($scope) {
$scope.toggleSelected = function () {
$scope.selected = !$scope.selected;
};
$scope.isSelected = function (user) {
return $scope.selected;
};
});
The div on top attempts to show a nested table upon clicking the list item, but nothing happens.
The div at the bottom attempts to show child td items upon clicking the list item and it works exactly as expected.
Does anyone have any idea what the problem is when I'm trying to expand to show a nested table using ng-switch? And how to solve it?
You have a two errors in your code.
First
In controller ListAndOneDetailCtrl on ng-click you don't have a function toggleSelected.
Second
In first table with controller ListAndOneDetailCtrl you don't have tag td in nested table.
See correct code in jsfiddle
angular.module('listAndDetails', [])
.value('users', [
{ name:'Damien', email:'damien#domain.com', desc:'Damien details go here...', country:'US', address:'address1'},
{ name:'Alex', email:'alex#domain.com', desc:'Alex details go here...', country:'UK', address:'address2'}
])
.controller('ListAndOneDetailCtrl', function ($scope, users) {
$scope.users = users;
$scope.selectUser = function (user) {
$scope.selectedUser = user;
};
$scope.isSelected = function (user) {
return $scope.selectedUser === user;
};
})
.controller('ListAndManyDetailsCtrl', function ($scope, users) {
$scope.users = users;
})
.controller('UserCtrl', function ($scope) {
$scope.toggleSelected = function () {
$scope.selected = !$scope.selected;
};
$scope.isSelected = function (user) {
return $scope.selected;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="listAndDetails">
<div>
<table class="table table-bordered" ng-controller="ListAndOneDetailCtrl">
<thead>
<tr>
<th>Name</th>
<th>e-mail</th>
</tr>
</thead>
<tbody ng-repeat="user in users" ng-click="selectUser(user)" ng-switch on="isSelected(user)">
<tr>
<td>{{user.name}}</td>
<td>{{user.email}}</td>
</tr>
<tr ng-switch-when="true" class="light-gray">
<td>
<table>
<tr>
<td>Country</td>
<td>Address</td>
<td>Description</td>
</tr>
<tr>
<td>{{user.country}}</td>
<td>{{user.address}}</td>
<td>{{user.desc}}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-controller="ListAndManyDetailsCtrl">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>e-mail</th>
</tr>
</thead>
<tbody ng-repeat="user in users" ng-controller="UserCtrl" ng-click="toggleSelected()" ng-switch on="isSelected()">
<tr>
<td>{{user.name}}</td>
<td>{{user.email}}</td>
</tr>
<tr ng-switch-when="true" class="light-gray">
<td>{{user.country}}</td>
<td>{{user.address}}</td>
<td>{{user.desc}}</td>
</tr>
</tbody>
</table>
</div>
</body>
There were two problems:
you needed a td section enclosing your table;
<tr>
<td>
<table>
<!-- table information -->
</table>
</td>
</tr>
the controller needed some modifications so that the selected user could have a value.
.controller('ListAndOneDetailCtrl', function ($scope, users) {
$scope.users = users;
$scope.toggleSelected = function(user) {
$scope.selectedUser = user;
};
$scope.selectUser = function (user) {
$scope.selectedUser = user;
};
$scope.isSelected = function (user) {
return $scope.selectedUser === user;
};
})
Here's an updated fiddle: https://jsfiddle.net/jp43agsb/2/

knockout js bindng issue when using template binding

lets say i have a following code
var Names = ['test1','test2','test3'];
function ViewModel() {
var self = this;
self.RegistraionInfo = ko.observableArray(Names);
self.ChangeSelection = function (data,event) {
fnChangeSelection(data);
}
self.tableRows = ko.observableArray([]);
self.addNewRow = function () {
self.tableRows.push(new tableRow('', self));
}
self.addNewRow();
}
function tableRow(number, ownerViewModel) {
var self = this;
self.number = ko.observable(number);
self.remove = function () {
ownerViewModel.tableRows.destroy(this);
}
ko.applyBindings(new ViewModel());
and in html
<table >
<thead>
<tr class="active">
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="template:{name:'data-tableRow', foreach: tableRows}"></tbody>
<tfoot>
<tr>
<td >
<img id="btnAddRowProcedure1" src=#Url.Content("~/Content/img/plus.png") data-bind="click: addNewRow" />
</td>
</tr>
</tfoot>
</table>
<script id="data-tableRow" type="text/html">
<tr>
<td >
<img id="btnDelete" src=#Url.Content("~/Content/img/close.png") data-bind="click: function(){ $data.remove(); }" />
</td>
<td><select data-bind="options:$root.RegistraionInfo, , event:{ change:$root.ChangeSelection}"></select></td>
</tr>
</script>
what im trying to do here is when user clicks the #btnAddRowProcedure1 link a new tablerow will be added. and inside the table row there is a dropdown that is bound to the Names array.when the user changes the dropdown selection the ChangeSelection function is called.
The Problem is that i want knock out to send currently selected Names array element as Data but knockout sending the tableRow as data.Is there a way to overcome this problem.Im still not sure why this works like this.
UPDATE
After the #Roy J changes i was able to get this to work.but now i have stumbled upon another problem (sorry im a noob at knockout).I want to add a button when ever the user changes the selection so i have added the following code to the ViewModel
self.displayAddBtn = ko.computed(function () {
if (self.tableRows.length == 0)
{
return false;
}
return self.tableRows[self.tableRows.length-1].selected() !="";
}, self);
this code is only executed once.when the user changes the selection this is code is not executed.can some one tell me how i can make this work
You need to have a value binding on your select. That's where the new value will show up when your change function is called.
var Names = ['test1', 'test2', 'test3'];
function ViewModel() {
var self = this;
self.RegistraionInfo = ko.observableArray(Names);
self.ChangeSelection = function(data, event) {
console.debug("Changed to:", data.selected());
}
self.tableRows = ko.observableArray([]);
self.addNewRow = function() {
self.tableRows.push(new tableRow('', self));
}
self.addNewRow();
}
function tableRow(number, ownerViewModel) {
var self = this;
self.number = ko.observable(number);
self.remove = function() {
ownerViewModel.tableRows.destroy(this);
};
self.selected = ko.observable(); // new! bound to select
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<table>
<thead>
<tr class="active">
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="template:{name:'data-tableRow', foreach: tableRows}"></tbody>
<tfoot>
<tr>
<td>
<img id="btnAddRowProcedure1" src=#Url.Content( "~/Content/img/plus.png") data-bind="click: addNewRow" />
</td>
</tr>
</tfoot>
</table>
<template id="data-tableRow">
<tr>
<td>
<img id="btnDelete" src=#Url.Content( "~/Content/img/close.png") data-bind="click: function(){ $data.remove(); }" />
</td>
<td>
<select data-bind="options:$root.RegistraionInfo, value:selected, event:{ change:$root.ChangeSelection}"></select>
</td>
</tr>
</template>

Accessing a JSON in AngularJS using ng-repeat

<table class="table table-striped" >
<thead>
<tr>
<th>Number</th>
<th>Zeroes</th>
</tr>
</thead>
<tbody ng-controller="ViewData as viewAll">
<tr ng-repeat="pop in viewAll.number">
<td>{{pop.number}}</td>
<td>{{pop.zeroes}}</td>
</tbody>
</table>
I have this table and I'm trying to get data to be outputted in it.
app.controller('ViewData', ['$http', '$scope',
function($http,$scope) {
$scope.viewAll = this;
$http.get('/someurl').success(function(data) {
$scope.viewAll.number = data;
});
}]);
This my controller getting the data.
{"number": {
"4": {
"zeroes": "5"
},
"5": {
"zeroes": "6"
},
"10": {
"zeroes": "7"
}}
And this is the data that /someurl is giving out to me.. Is there any way I can be able to handle this so I can be able to show it outside the table.
Thanks in advance for any kind of help given!
try:
<table class="table table-striped" >
<thead>
<tr>
<th>Number</th>
<th>Zeroes</th>
</tr>
</thead>
<tbody ng-controller="ViewData as viewAll">
<tr ng-repeat="{key, value} in viewAll.number">
<td>{{key}}</td>
<td>{{value.zeroes}}</td>
</tbody>
</table>
app.controller('ViewData', ['$http', '$scope',
function($http,$scope) {
var self = this;
$http.get('/someurl').success(function(data) {
self.number = data;
});
}]);

Categories

Resources