ng-repeat does not work on Angular JS - javascript

I have created a controller (movies.js) as below-
'use strict';
angular.module('clientApp')
.controller('MoviesCtrl', function ($scope) {
$scope.movies = [
{
title:'Star Wars!',
url:'http://www.google.com'
},
{
title: 'Star Wars2!',
url: 'http://www.google.com'
},
{
title: 'Star Wars3!',
url: 'http://www.google.com'
}
];
});
Now I'm trying to access the values of each objects using ng-repeat in movies.html-
<table class="table table-striped">
<thead>
<th>Title</th>
<th>URL</th>
</thead>
<tbody>
<tr ng-repeat="movie in movies">
<td> {{ movie.title }} </td>
<td> {{ movie.url }} </td>
</tr>
</tbody>
</table>
However, the values are not populated as expected. Can someone please provide any tips on where should I look to fix it?

Since you are assigning the array to this so
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope) {
this.movies = [{
title: 'Star Wars!',
url: 'http://www.google.com'
}, {
title: 'Star Wars2!',
url: 'http://www.google.com'
}, {
title: 'Star Wars3!',
url: 'http://www.google.com'
}];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
<div ng-controller="AppController as ctrl">
<table class="table table-striped">
<thead>
<th>Title</th>
<th>URL</th>
</thead>
<tbody>
<tr ng-repeat="movie in ctrl.movies">
<td>{{ movie.title }}</td>
<td>{{ movie.url }}</td>
</tr>
</tbody>
</table>
</div>
</div>
Or assign the array to the scope variable
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope) {
$scope.movies = [{
title: 'Star Wars!',
url: 'http://www.google.com'
}, {
title: 'Star Wars2!',
url: 'http://www.google.com'
}, {
title: 'Star Wars3!',
url: 'http://www.google.com'
}];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
<div ng-controller="AppController">
<table class="table table-striped">
<thead>
<th>Title</th>
<th>URL</th>
</thead>
<tbody>
<tr ng-repeat="movie in movies">
<td>{{ movie.title }}</td>
<td>{{ movie.url }}</td>
</tr>
</tbody>
</table>
</div>
</div>

You should try this
'use strict';
angular.module('validationApp' ,[])
.controller('MoviesCtrl', function ($scope) {
$scope.movies = [
{
title:'Star Wars!',
url:'http://www.google.com'
},
{
title: 'Star Wars2!',
url: 'http://www.google.com'
},
{
title: 'Star Wars3!',
url: 'http://www.google.com'
}
];
});

it should be
<table class="table table-striped">
<thead>
<th>Title</th>
<th>URL</th>
</thead>
<tbody>
<tr ng-repeat="movie in MoviesCtrl.movies">
<td> {{ movie.title }} </td>
<td> {{ movie.url }} </td>
</tr>
</tbody>
</table>
or you should bind it to $scope.movies

Still you won't be able to load external URLs. You need to make a filter to whitelist the external links. Refer below code.
angular.module('myApp')
.filter('trustUrl', function ($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
});
<td> {{ movie.url | trustUrl}} </td>

You need to inject $scope into your controller, and use that to bind your array to your view
.controller('MoviesCtrl', function($scope){
$scope.movies = [
{
title:'Star Wars!',
url:'http://www.google.com'
},{
title: 'Star Wars2!',
url: 'http://www.google.com'
},{
title: 'Star Wars3!',
url: 'http://www.google.com'
}
];
});
Also, don't forget that you need to specify in your view that there is a controller you want to use. For example, in your html:
<div ng-controller="MoviesCtrl">
<!-- any html you associate with your controller -->
</div>

Related

Ng-Repeat and ng-table issue

I'm new to Angular JS. The below Code is not working. I have tried with data table with Ng-Repeat. But It just showing the table without any sorting, pagination option.
Response Data looks like:
[{
\"ACCOUNT_LOCAL\":\"9007\",\"COMPANY_ID\":\"10001\",
\"ACCOUNT_GLOBAL\":\"100001\",\"IC_PARTNER\":\"9008\",
\"ACCOUNT_GLOBAL_DESC\":\"AUS GLOBAL\",
\"ACCOUNT_TYPE\":\"1\",\"COMPANY_DESC\":\"THIRDROCK\",
\"ACTIVE\":true
},
{
\"ACCOUNT_LOCAL\":\"9008\",\"COMPANY_ID\":\"10001\",
\"ACCOUNT_GLOBAL\":\"100001\",\"IC_PARTNER\":\"9009\",
\"ACCOUNT_GLOBAL_DESC\":\"AUS GLOBAL\",
\"ACCOUNT_TYPE\":\"1\",\"COMPANY_DESC\":\"THIRDROCK\",
\"ACTIVE\":true
},{
\"ACCOUNT_LOCAL\":\"9014\",\"COMPANY_ID\":\"10001\",
\"ACCOUNT_GLOBAL\":\"100001\",\"IC_PARTNER\":\"TEST\",
\"ACCOUNT_GLOBAL_DESC\":\"AUS GLOBAL\",
\"ACCOUNT_TYPE\":\"1\",\"COMPANY_DESC\":\"THIRDROCK\",
\"ACTIVE\":true
},
HTML file
<div ng-app="myApp" ng-controller="AccountMappingCtrl as vm">
<table ng-table="vm.tableParams" show-filter="true" class="table">
<tr ng-repeat="accountMap in $data">
<td title="'IC_PARTNER'" filter="{ IC_PARTNER: 'text'}" sortable="'IC_PARTNER'">
{{ accountMap.IC_PARTNER }}
</td>
<td title="'ACCOUNT_GLOBAL'" filter="{ ACCOUNT_GLOBAL: 'text'}" sortable="'ACCOUNT_GLOBAL'">
{ accountMap.ACCOUNT_GLOBAL }}
</td>
</tr>
</table>
</div>
JS File:
var app = angular.module('myApp', [ 'ngTable']);
app.controller('AccountMappingCtrl', ['$scope', '$http','$cookies', 'NgTableParams', function($scope, $http, $filter, NgTableParams) {
$http.get("http://localhost:52087/api/accountmapping")
.then(function(response) {
var convertJson = angular.fromJson(response.data);
var self = this;
var data = convertJson;
self.tableParams = new NgTableParams({}, { dataset: data});
});
});
var myApp = angular.module('myApp',["ngTable"]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
myApp.controller('MyCtrl',function($scope,NgTableParams){
$scope.name = 'Superhero';
var data = [{
"ACCOUNT_LOCAL":"9007","COMPANY_ID":"10001",
"ACCOUNT_GLOBAL":"100001","IC_PARTNER":"9008",
"ACCOUNT_GLOBAL_DESC":"AUS GLOBAL",
"ACCOUNT_TYPE":"1","COMPANY_DESC":"THIRDROCK",
"ACTIVE":true
},
{
"ACCOUNT_LOCAL":"9008","COMPANY_ID":"10001",
"ACCOUNT_GLOBAL":"100001","IC_PARTNER":"9009",
"ACCOUNT_GLOBAL_DESC":"AUS GLOBAL",
"ACCOUNT_TYPE":"1","COMPANY_DESC":"THIRDROCK",
"ACTIVE":true
},{
"ACCOUNT_LOCAL":"9014","COMPANY_ID":"10001",
"ACCOUNT_GLOBAL":"100001","IC_PARTNER":"TEST",
"ACCOUNT_GLOBAL_DESC":"AUS GLOBAL",
"ACCOUNT_TYPE":"1","COMPANY_DESC":"THIRDROCK",
"ACTIVE":true
}]
//your HTTP call here
$scope.tableParams = new NgTableParams({}, { dataset: data});
})
<div ng-app="myApp" ng-controller="MyCtrl">
Hello, {{name}}!
<table ng-table="tableParams" show-filter="true" class="table">
<tr ng-repeat="accountMap in $data">
<td title="'IC_PARTNER'" filter="{ IC_PARTNER: 'text'}" sortable="'IC_PARTNER'">
{{ accountMap.IC_PARTNER }}
</td>
<td title="'ACCOUNT_GLOBAL'" filter="{ ACCOUNT_GLOBAL: 'text'}" sortable="'ACCOUNT_GLOBAL'">
{{ accountMap.ACCOUNT_GLOBAL }}
</td>
</tr>
</table>
</div>
<link rel="stylesheet"; href="https://unpkg.com/ng-table#2.0.2/bundles/ng-table.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<script src="https://unpkg.com/ng-table#2.0.2/bundles/ng-table.min.js"></script>
There is type in your code { accountMap.ACCOUNT_GLOBAL }} should be {{ accountMap.ACCOUNT_GLOBAL }}
I have made fiddle of your test data. Please check this fiddle and it is working fine.

Vue.js 2 components parent child item not defined

I am new to vue and I am getting the error referenceError: items is not defined. Can anyone see why this happens or give me some pointers?
I think it has something to do with the items not being set on first look at the template.
My code:
<div id="root">
<task-list></task-list>
<template id="my-parent">
<table>
<thead>
<tr>
<th>Name</th>
<th>id</th>
</tr>
</thead>
<tbody>
<tr is="task" v-for="item in items" :item="item"></tr>
</tbody>
</table>
</template>
<template id="my-child">
<tr>
<td></td>
<td>{{ item.name }}</td>
<td>{{ item.id }}</td>
</tr>
</template>
</div>
<script>
Vue.component('task-list', {
template: '#my-parent',
data: function() {
return {
items: []
}
},
methods: {
getMyData: function(val) {
var _this = this;
$.ajax({
url: 'vuejson.php',
method: 'GET',
success: function (data) {
console.log(data);
_this.items = data;
},
error: function (error) {
alert(JSON.stringify(error));
}
})
}
},
mounted: function () {
this.getMyData("0");
}
});
Vue.component('task', {
template: '#my-child',
props: ['item'],
data: function() {
return {
item: {}
}
}
});
new Vue({
el: "#root",
});
</script>
Here is working modified code:
<template id="my-child">
<tr>
<td>{{ item.name }}</td>
<td>{{ item.id }}</td>
</tr>
</template>
<template id="my-parent">
<table>
<thead>
<tr>
<th>Name</th>
<th>id</th>
</tr>
</thead>
<tbody>
<tr is="task" v-for="item in items" :item="item"></tr>
</tbody>
</table>
</template>
<div id="root">
<task-list></task-list>
</div>
And js:
Vue.component('task-list', {
template: '#my-parent',
data: function() {
return {
items: []
}
},
methods: {
getMyData: function(val) {
var _this = this;
_this.items = [{name: '1.name', id: 1}];
}
},
mounted: function () {
this.getMyData("0");
}
});
Vue.component('task', {
template: '#my-child',
props: ['item'],
data: function() {
return {
}
}
});
new Vue({
el: "#root",
});
jsfiddle
It would be much easier to you to work with vue, if you do some tutorials first:)
edit:
And one more thing: if you declare property(item in your case), dont use that name in data.
So, what I did:
- placed templates outside of your root element
- removed "item" from data
You should describe templates outside div#root.
Example
<div id="root">
<task-list></task-list>
</div>
<template id="my-parent">
<table>
<thead>
<tr>
<th>Name</th>
<th>id</th>
</tr>
</thead>
<tbody>
<tr is="task" v-for="item in items" :item="item"></tr>
</tbody>
</table>
</template>
<template id="my-child">
<tr>
<td></td>
<td>{{ item.name }}</td>
<td>{{ item.id }}</td>
</tr>
</template>
Because if they are in #root they are part of vue instance for it, and there is no items in it.
new Vue({
el: "#root",
//no items
});

ngTable dynamic with columns doesn't show column titles

In this plunk I have two tables, one regular ng-table and an ng-table-dynamic with columns. Both point to the same data.
The second table doesn't show column titles, how to fix that?
HTML
<br/> Table 1
<table ng-table="tableParams" class="table table-bordered table-hover">
<tbody>
<tr ng-repeat="u in data" ng-dblclick="alert('double click')">
<td title="'User ID'">{{ u.uid }}</td>
<td title="'Group'">{{ u.ugr }}</td>
</tr>
</tbody>
</table>
<br/> Table 2
<table ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
<tr ng-repeat="row in data">
<td title="col.nm" ng-repeat="col in cols">{{row[col.nm]}}</td>
</tr>
</table>
Javascript:
var app = angular.module('app', ['ngTable']);
app.controller('myCtl', function($scope,NgTableParams) {
$scope.cols = [ {nm:'uid'}, {nm:'ugr'} ];
$scope.data = [
{ uid: 'User 1',ugr: 'Group 1'},
{ uid: 'User 2', ugr: 'Group 2'}
];
$scope.tableParams = new NgTableParams({dataset: $scope.data});
});
You're missing the title property within your cols:
$scope.cols = [ {nm:'uid', title: 'User ID'}, {nm:'ugr', title: 'Group ID'} ];
See this plunkr.

Nested ng-repeat in Angular JS table

I am a newbie to Angular JS.
I have been trying iterate through a model collection and display the same in a table.
The Model looks like :
var myModule = angular
.module("myModule", [])
.controller("myController", function ($scope) {
var countries = [
{
name: "UK",
cities: [
{name: "London"},
{name: "Birmingham" },
{name: "Manchestar" }
],
flag:"/Images/UK.gif"
},
{
name: "USA",
cities: [
{name: "Los Angeles"},
{name: "Houston"},
{name: "Florida"},
],
flag:"/Images/USA.png"
}
];
$scope.countries = countries;
});
And I want the table structure to be
Country City1 City2 City3 Flag
UK London Birmingham Manchestar .....
USA ...... ......... ......... .....
But I could not do the same in the html page.
So far the code looks like :
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="myModule">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/MyModuleScript.js"></script>
</head>
<body ng-controller="myController">
<div>
<table>
<thead>
<tr>
<th>Country</th>
<th>City 1</th>
<th>City 2</th>
<th>City 3</th>
<th>Flag</th>
</tr>
</thead>
<tbody ng-repeat="country in countries">
<tr ng-repeat="city in country.cities">
<td>{{ country.name }}</td>
<td>
{{......}}
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
What I need to do to achieve the same ? Please explain.
try this. you must put ng-repeat on td instead of row.
var myModule = angular
.module("myModule", [])
.controller("myController", function ($scope) {
$scope.countries = [
{
name: "UK",
cities: [
{name: "London"},
{name: "Birmingham" },
{name: "Manchestar" }
],
flag:"/Images/UK.gif"
},
{
name: "USA",
cities: [
{name: "Los Angeles"},
{name: "Houston"},
{name: "Florida"},
],
flag:"/Images/USA.png"
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myModule" ng-controller="myController">
<div>
<table>
<thead>
<tr>
<th>Country</th>
<th>City 1</th>
<th>City 2</th>
<th>City 3</th>
<th>Flag</th>
</tr>
</thead>
<tbody ng-repeat="country in countries">
<tr>
<td>{{ country.name }}</td>
<td ng-repeat="city in country.cities">
{{city.name}}
</td>
<td><img ng-src="{{country.flag}}"></td>
</tr>
</tbody>
</table>
</div>
</div>
repeat a little and it works as you need it.
<tbody ng-repeat="country in countries">
<tr >
<td >{{ country.name }}</td>
<td ng-repeat="city in country.cities">
{{city.name}}
</td>
<td><img ng-src="{{country.flag}}"></td>
</tr>
</tbody>
var myModule = angular
.module("myModule", [])
.controller("myController", function ($scope) {
var countries = [
{
name: "UK",
cities: [
{name: "London"},
{name: "Birmingham" },
{name: "Manchestar" }
],
flag:"/Images/UK.gif"
},
{
name: "USA",
cities: [
{name: "Los Angeles"},
{name: "Houston"},
{name: "Florida"},
],
flag:"/Images/USA.png"
}
];
$scope.countries = countries;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="myModule">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
</head>
<body ng-controller="myController">
<div>
<table>
<thead>
<tr>
<th>Country</th>
<th>City 1</th>
<th>City 2</th>
<th>City 3</th>
<th>Flag</th>
</tr>
</thead>
<tbody ng-repeat="country in countries">
<tr >
<td >{{ country.name }}</td>
<td ng-repeat="city in country.cities">
{{city.name}}
</td>
<td><img ng-src="{{country.flag}}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
var myModule = angular
.module("myModule", [])
.controller("myController", function ($scope) {
var countries = [
{
name: "UK",
cities: [
{name: "London"},
{name: "Birmingham" },
{name: "Manchestar" }
],
flag:"/Images/UK.gif"
},
{
name: "USA",
cities: [
{name: "Los Angeles"},
{name: "Houston"},
{name: "Florida"},
],
flag:"/Images/USA.png"
}
];
$scope.countries = countries;
});
Everything is fine except your HTML.
Your first ng-repeat for countries should be for <tr>
The second one should be for <td>
tbody is not supposed to be repeated as seen by some of the answers here. As per w3c HTML5 Specs tbody tbody is single element after thead
You are on the right track just remember that ng-repeat will repeat the element on which it is specified as attribute.
<tbody>
<tr ng-repeat="country in countries">
<td >{{ country.name }}</td>
<td ng-repeat="city in country.cities">
{{city.name}}
</td>
<td><img ng-src="{{country.flag}}"></td>
</tr>
</tbody>

AngularJS ng-repeat-start with limitTo doesn't work

I have a list of several objects and at the beginning I want to load just some of them. I took a look at the statement ng-repeat, but I need to have a structure like this:
<table class="table table-hover table-hidden">
<thead>
<tr>
...
</tr>
</thead>
<tbody>
<tr ng-repeat-start="object in objects | filter:query | orderBy:predicate:reverse" ng-init="isCollapsed=true">
...
</tr>
<tr ng-repeat-end class="more">
...
</tr>
</tbody>
</table>
I tried to apply the statement limitTo inside ng-repeat-start, in this way:
<tr ng-repeat-start="object in objects | filter:query | orderBy:predicate:reverse| limitTo: limit" ng-init="isCollapsed=true">
and on controller I wrote:
$scope.limit = 10;
$scope.incrementLimit = function () {
$scope.limit += 10;
};
The function incrementLimit is called by a click on hyperlink
<a href ng-click="incrementLimit()">more</a>
The list of objects is instantiated and filled (with all the elements) when the page loads.
With my approach at the beginnig are loaded and showed first 10 elements correctly, and when I click on "more" the variable $scope.limitis incremented, but on the page nothing happens. Anyone can explain me why?
limitTo is working fine inside ng-repeat-start
Take a look at this
var app = angular.module('myApp', []);
app.controller('Controller', function ($scope) {
$scope.limit = 1;
$scope.incrementLimit = function () {
$scope.limit += 1;
};
$scope.data = [{
title: 'Foo',
text: 'Lorem'
}, {
title: 'Bar',
text: 'Iste'
}, {
title: 'Jon',
text: 'Fat'
}, {
title: 'Los',
text: 'Ice'
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<div ng-app='myApp' ng-controller="Controller">
<table border="2" class="table table-hover table-hidden">
<thead>
<tr>...</tr>
</thead>
<tbody>
<tr ng-repeat-start="object in data | filter:query | orderBy:predicate:reverse| limitTo: limit" ng-init="isCollapsed=true" ng-bind="object.title">...</tr>
<tr ng-repeat-end class="more">...</tr>
</tbody>
</table>
more
</div>
Please check the below code and fiddle it is working fine
<body ng-controller="myController">
<button ng-click="incrementLimit()" >increment</button> <br/>
<table class="table table-hover table-hidden">
<thead>
<tr clospan="3">
Head
</tr>
</thead>
<tbody>
<tr ng-repeat-start="friend in objects|limitTo: limit" ng-init="isCollapsed=true">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>
<tr ng-repeat-end class="more">
<td colspan="3">Footer</td>
</tr>
</tbody>
</table>
</table>
</body>
js code
app = angular.module("app", []);
app.controller("myController", function($scope) {
$scope.objects =
[{
name: 'John',
phone: '555-1212',
age: 10
}, {
name: 'Mary',
phone: '555-9876',
age: 19
}, {
name: 'Mike',
phone: '555-4321',
age: 21
}, {
name: 'Adam',
phone: '555-5678',
age: 35
}, {
name: 'Julie',
phone: '555-8765',
age: 29
}];
$scope.limit = 2;
$scope.incrementLimit = function () {
$scope.limit += 1;
};
});
Fiddle http://jsbin.com/hoguxexuli/1/edit
I solved my problem. Basically I put the hyperlink in a different div, so the controller and the $scope were also different. It was a stupid carelessness.

Categories