How would I go about refactoring my code to be more concise:
const an1 = document.getElementById("an1");
const bt1 = document.getElementById("bt1");
bt1.addEventListener("click", () => {
if (an1.value.toLowerCase() === "test") {
document.getElementById("bt1").style.display = "none";
document.getElementById("an1").style.display = "none";
document.getElementById("wo1").style.display = "initial";
} else {
bt1.innerText = "Wrong!";
document.getElementById("bt1").style.background = "red";
}
});
const an2 = document.getElementById("an2");
const bt2 = document.getElementById("bt2");
bt2.addEventListener("click", () => {
if (an2.value.toLowerCase() === "test1") {
document.getElementById("bt2").style.display = "none";
document.getElementById("an2").style.display = "none";
document.getElementById("wo2").style.display = "initial";
} else {
bt2.innerText = "Wrong!";
document.getElementById("bt2").style.background = "red";
}
});
<tr>
<td class="c1"><input id="an1" placeholder="test" type="text" onblur="this.value=removeSpaces(this.value);" /><a id="wo1" style="display: none;">test</a><button id="bt1">Submit</button></td>
<td class="c1">test</td>
</tr>
<tr>
<td class="c2"><input id="an2" placeholder="test1" type="text" onblur="this.value=removeSpaces(this.value);" /><a id="wo2" style="display: none;">test1</a><button id="bt2">Submit</button></td>
<td class="c2">test1</td>
</tr>
Try below code, update the arrays if this fucntionality requires for others field too.
// change below arrays if you need this functionality for more fields
const expectedElementAnswer = [{ id: 'an1', expectAns: 'test' }, { id: 'an2', expectAns: 'test1' }];
const btnElementList = [
[{ id: 'bt1', displayValue: 'none' },{ id: 'an1', displayValue: 'none' }, { id: 'wo1', displayValue: 'initial' }],
[{ id: 'bt2', displayValue: 'none' }, { id: 'an2', displayValue: 'none' }, { id: 'wo2', displayValue: 'initial' }]
];
document.getElementById('myTable').addEventListener('click', (event) => {
const curElemetId = event.target.id;
const btnIndex = (curElemetId === 'bt1') ? 1 : (curElemetId === 'bt2') ? 2 : -1;
if ((btnIndex === 1) || (btnIndex === 2)) {
const idx = btnIndex - 1;
const { id, expectAns } = expectedElementAnswer[idx];
if (getElementValue(id).toLowerCase() === expectAns) {
changeDisplayStyles(idx);
} else {
setErrorWarning(curElemetId);
}
}
});
function changeDisplayStyles(idx) {
btnElementList[idx].forEach(({ id, displayValue }) => {
setDisplayStyle(id, displayValue)
});
}
function setDisplayStyle(displayId, value) {
document.getElementById(displayId).style.display = value;
}
function setErrorWarning(displayId, bgColor = 'red') {
const element = document.getElementById(displayId);
element.innerText = 'Wrong!';
element.style.background = bgColor;
}
function getElementValue(id) {
const value = document.getElementById(id)?.value || '';
return value;
}
<table id="myTable">
<tr>
<td class="c1">
<input id="an1" placeholder="test" type="text"/>
<a id="wo1" style="display: none;">test</a>
<button id="bt1">Submit</button>
</td>
<td class="c1">test</td>
</tr>
<tr>
<td class="c2">
<input id="an2" placeholder="test1" type="text"/>
<a id="wo2" style="display: none;">test1</a>
<button id="bt2">Submit</button>
</td>
<td class="c2">test1</td>
</tr>
</table>
I have an AJAX function that returns this json array when the page loads.
{
"ydtd4EGwIgb9QAPekbzBUXq9ZXp2":{
"Highscore":1000,
"username":"ash"
},
"qo80G8bFPsRkujLm9qWtASz0TE32":{
"Highscore":900,
"username":"pink"
},
"oyWEgmEAMENvr8zTGd6gqCMyVPS2":{
"Highscore":800,
"username":"orange"
},
"acjqiNwlxqfZsSaRBYKoaVOqomh1":{
"Highscore":700,
"username":"white"
},
"IhnWPgRT1gVLrxLhD6ZvNn9migX2":{
"Highscore":"700",
"username":"RED"
},
"ZeGUezY38gcHX0NXaommRPR65cR2":{
"Highscore":600,
"username":"blue"
},
"A41jXf0wmQQqzUlAu6WAuaf04Nk2":{
"Highscore":600,
"username":"mary"
},
"Vm4jMNI83mSFdN4wYbfJ6C7ecEH3":{
"Highscore":500,
"username":"green"
},
"PtTdYXIWYAeMOrIPE8FBN66F9L32":{
"Highscore":400,
"username":"gray"
},
"OeUusBMYjBSYg6UJ8I3eze2TUHi2":{
"Highscore":300,
"username":"yellow"
},
"9xn2ZH9m63Rs34Erkz6N69kuE653":{
"Highscore":100,
"username":"violet"
}
}
what I want is to append only the high score and the username but not the uid into the table so it would populate the table once the page loads.
<table class="table table-borderless table-dark table-striped" id="records_table">
<tr>
<th style="text-align: center;">Rank</th>
<th style="text-align: center;">Username</th>
<th style="text-align: center;">Highscore</th>
</tr>
</table>
I tried each loop but I can't get it to work, any help is appreciated.
var obj ={
"ydtd4EGwIgb9QAPekbzBUXq9ZXp2":{
"Highscore":1000,
"username":"ash"
},
"qo80G8bFPsRkujLm9qWtASz0TE32":{
"Highscore":900,
"username":"pink"
},
"OeUusBMYjBSYg6UJ8I3eze2TUHi2":{
"Highscore":1200,
"username":"yellow"
},
"9xn2ZH9m63Rs34Erkz6N69kuE653":{
"Highscore":100,
"username":"violet"
}
}
var res = Object.keys(obj).map((data)=>{
var innerdata = obj[data];
var score = innerdata.Highscore;
var username = innerdata.username;
return [score,username]
})
var result = res.sort((a,b)=> b[0]-a[0])
var final = Object.keys(result).map((rank)=>{
var Rank =Number(rank)+1;
var score = result[rank][0];
var name = result[rank][1]
document.querySelector('table > tbody').innerHTML += `
<tr><td>${Rank}</td><td>${name}</td><td>${score}</td></tr>`;
})
It is simple. You just need to iterate over each object.
Like this:
const data = {
"ydtd4EGwIgb9QAPekbzBUXq9ZXp2":{
"Highscore":1000,
"username":"ash"
},
"qo80G8bFPsRkujLm9qWtASz0TE32":{
"Highscore":900,
"username":"pink"
},
"oyWEgmEAMENvr8zTGd6gqCMyVPS2":{
"Highscore":800,
"username":"orange"
},
"acjqiNwlxqfZsSaRBYKoaVOqomh1":{
"Highscore":700,
"username":"white"
},
"IhnWPgRT1gVLrxLhD6ZvNn9migX2":{
"Highscore":"700",
"username":"RED"
},
"ZeGUezY38gcHX0NXaommRPR65cR2":{
"Highscore":600,
"username":"blue"
},
"A41jXf0wmQQqzUlAu6WAuaf04Nk2":{
"Highscore":600,
"username":"mary"
},
"Vm4jMNI83mSFdN4wYbfJ6C7ecEH3":{
"Highscore":500,
"username":"green"
},
"PtTdYXIWYAeMOrIPE8FBN66F9L32":{
"Highscore":400,
"username":"gray"
},
"OeUusBMYjBSYg6UJ8I3eze2TUHi2":{
"Highscore":300,
"username":"yellow"
},
"9xn2ZH9m63Rs34Erkz6N69kuE653":{
"Highscore":100,
"username":"violet"
}
};
for (const key in data) {
const {Highscore, username, rank = "???"} = data[key];
document.querySelector('table > tbody').innerHTML += `
<tr><td>${rank}</td><td>${username}</td><td>${Highscore}</td></tr>`;
}
<table>
<thead>
<th style="text-align: center;">Rank</th>
<th style="text-align: center;">Username</th>
<th style="text-align: center;">Highscore</th>
</thead>
<tbody></tbody>
</table>
The pagination page numbers looks weird and lengthy. I want to display only some of the page numbers in frontend. my code It's working ok, but not good when there's large numbers of pages. so i'm using twbsPagination in function renderPagination. when i run my code i'm getting the error Uncaught TypeError: $(...).twbsPagination is not a function. twbsPagination source is script:src pagination.js. but when i run twbsPagination separate without any function it's working fine. how can i run twbsPagination with my code?
index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
<script src="homer/vendor/jquery/dist/jquery.min.js"></script>
<script src="desk/vendor/pagination/pagination.min.js"></script>
<script src="desk/components/approved2.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody id="approvedList">
</tbody>
</table>
<nav aria-label="Page navigation example">
<ul class="pagination"></ul>
</nav>
index.js
const localURL = "http://localhost:8000/"
// output Html
const Story = document.querySelector('#approvedList');
const pagination = document.querySelector('.pagination');
$(function () {
var page = 1,
records = 1,
totalRecords = 0,
search = '';
// Run on page load
fetchData();
setInterval(fetchData, 2000);
// data filtering
$("#search-input").keyup(function (e) {
let value = e.target.value
fetchData(search = value);
});
// Show Records limits
$("#records").click(function (e) {
let value = e.target.value
fetchData(records = value);
});
// Previous Page
$('[aria-label="Previous"]').click(function () {
if (page > 1) {
page--;
}
fetchData();
});
// Next page
$('[aria-label="Next"]').click(function () {
if (page * records < totalRecords) {
page++;
}
fetchData();
});
// data fetching from API
function fetchData() {
$.ajax({
url: "http://localhost:8000/api/approved/",
type: "GET",
data: {
page: page,
records: records,
search: search
},
success: function (res) {
totalRecords = res.count
Story.innerHTML = '';
res.results.map((object) => {
Story.innerHTML +=
`<tr>
<td> ` + object.id + `</td>
<td>${object.id}` + object.title + `</td>
</tr>`;
})
Pagination();
}
})
}
function Pagination() {
// let pagesNumbers = Math.ceil(totalRecords / records);
let pagesNumbers = Math.ceil(totalRecords / records);
$('#pagination').twbsPagination({
totalPages: pagesNumbers,
visiblePages: 5,
onPageClick: function (event, page) {
$('#page-content').text('Page ' + page);
}
});
}
})
You cannot add twice the jQuery library.
I don't know the pagination.min.js and approved2.js libraries but I know you can add the twbsPagination as follow:
<script src="https://cdnjs.cloudflare.com/ajax/libs/twbs-pagination/1.4.2/jquery.twbsPagination.min.js"></script>
Moreover, this line is wrong:
let pagesNumbers = Math.ceil(totalRecords / records);
pagesNumbers needs to be at least 1.
The snippet with your code:
const fakeData = {
data: [{
row: 1,
name: 'a'
}, {
row: 2,
name: 'b'
}, {
row: 3,
name: 'c'
}, {
row: 4,
name: 'd'
}, {
row: 5,
name: 'e'
}, {
row: 6,
name: 'f'
}, {
row: 7,
name: 'g'
}],
totalRecords: 7
};
// output Html
const Story = document.querySelector('#approvedList');
const pagination = document.querySelector('.pagination');
$(function () {
var page = 1,
records = 1,
totalRecords = 0,
search = '';
// Run on page load
fetchData();
// data fetching from API
function fetchData() {
totalCount = fakeData.totalCount;
Story.innerHTML = '';
fakeData.data.slice((page - 1) * records, page * records).map((object) => {
Story.innerHTML +=
`<tr >
<td>${object.row}</td>
<td>${object.name}</td>
</tr >
`;
})
renderPagination();
}
function renderPagination() {
let pagesNumbers = Math.ceil(totalRecords / records) || 1;
$('.pagination').twbsPagination({
totalPages: pagesNumbers,
visiblePages: 5,
onPageClick: function (event, page) {
$('#page-content').text('Page ' + page);
}
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twbs-pagination/1.4.2/jquery.twbsPagination.min.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody id="approvedList">
</tbody>
</table>
<nav aria-label="Page navigation example">
<ul class="pagination"></ul>
</nav>
Trying to make a load more button, when user click it add 10 more item into the page. But the button code is not running smoothly... I still see all items in the page, and also there is no error in the console too.. of course button is not working.
Additionally, trying to make it run with the filter function.. Thank you for any example, help.
data() {
return {
estates:[],
moreEstates: [],
moreEstFetched: false,
}
},
mounted() {
axios.get('/ajax').then((response) => {
this.estates = response.data
this.insertMarkers();
});
},
methods: {
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then((response) => {
this.moreEstates = response.data;
this.estates = this.moreEstates.splice(0, 10);
this.moreEstFetched = true;
});
}
var nextEsts = this.moreEstFetched.splice(0, 10);
this.estates.push(nextEsts);
},
},
computed: {
one: function () {
let filteredStates = this.estates.filter((estate) => {
return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
}
filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
return filteredStates;
},
},
<table class="table table-hover">
<thead>
<tr style="background-color: #fff ">
<th scope="col">イメージ</th>
<th style="width:175px;"scope="col">物件名</th>
<th style="width:175px;"scope="col">住所</th>
<th scope="col">販売価格</th>
<th scope="col">間取り</th>
<th scope="col">専有面積</th>
<th scope="col">坪単価</th>
<th style="width:90px;" scope="col">物件詳細</th>
</tr>
</thead>
<tbody>
<tr v-for="estate in one">
<td><img id="image" :src="estate.image" alt=""></td>
<td>{{estate.building_name}}</td>
<td>{{estate.address}}</td>
<td>{{priceSep(estate.price)}} 万円</td>
<td>{{estate.rooms}}</td>
<td>{{xtendSep(estate.extend)}} m²</td>
<td>{{estate.m2_price}}</td>
<td><a :href="/pages/+estate.id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-primary loadmorebutton" #click="handleButton">Load more</button>
As #pyriand3r pointed out that the axios request is async you can do something like this with async/await without modifiyng too much the code.
methods: {
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then(async (response) => {
this.moreEstates = await response.data;
this.estates = this.moreEstates.splice(0, 10);
this.moreEstFetched = true;
});
}
// Also you cant splice a boolean only arrays.
var nextEsts = this.moreEstFetched.splice(0, 10);
this.estates.push(nextEsts);
},
},
See: Async/await in JavaScript
Made some changes to your code, read the comment to understand.
But this is the same as the last post you added.
data() {
return {
visible:true ,
estates:[],
moreEstates: [],
moreEstFetched: false,
size: 10,
selectedPage:0,
init: false,
}
},
updated: function () { // when loaded, trigger only once
if (!this.init) {
this.handleButton();
this.init = true;
}
},
mounted() {
// why is this here, you should only have handleButton to load the data
// axios.get('/ajax').then((response) => {
// this.estates =this.filterData(response.data)
// this.insertMarkers();
// this.showMore();
// });
},
methods: {
filterData: function (data) {
let filteredStates = data.filter((estate) => {
return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
}
filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
return filteredStates;
},
showMore: function(){
if (Math.ceil( this.moreEstates.length / this.size) <= this.selectedPage +1 ){
this.selectedPage++;
// using slice is better where splice changes the orginal array
var nextEsts = this.moreEstFetched.slice((this.selectedPage * this.size), this.size);
this.estates.push(nextEsts);
}else this. visible= true; // hide show more
},
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then((response) => {
// filter the whole data at once
this.moreEstates = this.filterData(response.data);
this.moreEstFetched = true;
// not sure what this is, i moved it here
this.insertMarkers();
this.showMore();
});
}else this.showMore();
},
},
<table class="table table-hover">
<thead>
<tr style="background-color: #fff ">
<th scope="col">イメージ</th>
<th style="width:175px;"scope="col">物件名</th>
<th style="width:175px;"scope="col">住所</th>
<th scope="col">販売価格</th>
<th scope="col">間取り</th>
<th scope="col">専有面積</th>
<th scope="col">坪単価</th>
<th style="width:90px;" scope="col">物件詳細</th>
</tr>
</thead>
<tbody>
<tr v-for="estate in estates">
<td><img id="image" :src="estate.image" alt=""></td>
<td>{{estate.building_name}}</td>
<td>{{estate.address}}</td>
<td>{{priceSep(estate.price)}} 万円</td>
<td>{{estate.rooms}}</td>
<td>{{xtendSep(estate.extend)}} m²</td>
<td>{{estate.m2_price}}</td>
<td><a :href="/pages/+estate.id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button v-if="visible" class="btn btn-primary loadmorebutton" #click="handleButton">Load more</button>
actually, I am not sure it is the best way but, tried much more simplest way to achieve it...
data() {
return {
moreEstates: 10,
}
},
<table class="table table-hover">
<tbody>
<tr v-if="moreIndex < one.length" v-for="moreIndex in moreEstates">
<td><img id="image" :src="one[moreIndex].image" alt=""></td>
<td>{{one[moreIndex].building_name}}</td>
<td>{{one[moreIndex].address}}</td>
<td>{{priceSep(one[moreIndex].price)}} 万円</td>
<td>{{one[moreIndex].rooms}}</td>
<td>{{xtendSep(one[moreIndex].extend)}} m²</td>
<td>{{one[moreIndex].m2_price}}</td>
<td><a :href="/pages/+one[moreIndex].id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-primary loadmorebutton" #click="moreEstates += 10">次の10件を見る</button>
I get following response from database. about array of classes where classes are nested in groups and finally students.
"Response":[
{
"Id":1,"Name":"Class 1","Location":"Building 1","Groups":[
{
"Id":1,"Name":"GB1","Students":[
{
"Id":1,"Name":"Mike","RollNo":"1","Performance":{
"Id":1,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":2,"Name":"John","RollNo":"2","Performance":{
"Id":2,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":3,"Name":"Muffin","RollNo":"3","Performance":{
"Id":3,"Math":"90","Physics":"90","English":"90"
}
}
]
}, {
"Id":2,"Name":"GB2","Students":[
{
"Id":4,"Name":"Ema","RollNo":"1","Performance":{
"Id":4,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":5,"Name":"Sunny","RollNo":"2","Performance":{
"Id":5,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":6,"Name":"Jen","RollNo":"3","Performance":{
"Id":6,"Math":"90","Physics":"90","English":"90"
}
}
]
}
]
},{
"Id":2,"Name":"Class 2","Location":"Building 1","Groups":[
{
"Id":3,"Name":"G1","Students":[
{
"Id":7,"Name":"Ron","RollNo":"1","Performance":{
"Id":7,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":8,"Name":"Kaka","RollNo":"2","Performance":{
"Id":8,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":9,"Name":"Mark","RollNo":"3","Performance":{
"Id":9,"Math":"90","Physics":"90","English":"90"
}
}
]
}, {
"Id":4,"Name":"G2","Students":[
{
"Id":10,"Name":"Lily","RollNo":"1","Performance":{
"Id":10,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":11,"Name":"Lina","RollNo":"2","Performance":{
"Id":11,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":12,"Name":"Linda","RollNo":"3","Performance":{
"Id":12,"Math":"90","Physics":"90","English":"90"
}
}
]
}
]
}
]
Now I want to create a table like this using colspan.
Could anyone help me to do this using ng-repeat and angularjs ? can't figure out how to merge this columns dynamically. So far I managed to do last part using flatten array option.
To solve this problem, you will need to ng-repeat inside the <td> instead of <tr>, for most of the time. Other than that, it is just rather tedious work parsing around your object and align them in the manner you want.
Here is the plnkr: http://plnkr.co/edit/aNVrMa4E8gLkVYlxzdHF?p=preview
I am poor at css. Maybe you can do something about that.
Although in this solution I had to add add few JavaScript method I still expect to see a better solution and accept as an answer. DEMO
<!DOCTYPE html>
<html ng-app = "demo">
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller = "demoCtrl">
<h1>Hello Plunker!</h1>
<br>
<table>
<tr>
<td>Class name</td>
<td colspan="{{lengthCount(r)}}" ng-repeat ="r in response" >
{{r.Name}}
</td>
</tr>
<tr>
<td>Group name</td>
<td colspan="{{gr.Students.length}}" ng-repeat ="gr in Groups" >
{{gr.Name}}
</td>
</tr>
<tr>
<td>Student name</td>
<td ng-repeat ="st in Studs" >
{{st.Name}}
</td>
</tr>
<tr>
<td>Maths</td>
<td ng-repeat ="st in Studs" >
{{st.Performance.Math}}
</td>
</tr>
<tr>
<td>Physics</td>
<td ng-repeat ="st in Studs" >
{{st.Performance.Physics}}
</td>
</tr>
<tr>
<td>English</td>
<td ng-repeat ="st in Studs" >
{{st.Performance.English}}
</td>
</tr>
</table>
<br>
</body>
</html>
Code goes here
angular.module("demo",[])
.controller("demoCtrl", ['$scope', function($scope){
$scope.response = response;
function flattenArray(array, fn) {
var output = [];
console.log("<i was flatten here");
for (var i = 0; i < array.length; ++i) {
var result = fn(array[i]);
if (result)
output = output.concat(result);
}
return output;
}
$scope.lengthCount = function(obj) {
var k = 0;
console.log("<i was flatten here");
for (var i = 0; i < obj.Groups.length; ++i) {
k= k+ obj.Groups[i].Students.length;
}
return k;
}
$scope.Groups = flattenArray($scope.response, function (item) {
console.log("<i was here");
return item.Groups;
});
$scope.Studs = flattenArray($scope.Groups, function (item) {
console.log("<i was here");
return item.Students;
});
}]);
var response = [{
"Id":1,"Name":"Class 1","Location":"Building 1","Groups":[
{
"Id":1,"Name":"GB1","Students":[
{
"Id":1,"Name":"Mike","RollNo":"1","Performance":{
"Id":1,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":2,"Name":"John","RollNo":"2","Performance":{
"Id":2,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":3,"Name":"Muffin","RollNo":"3","Performance":{
"Id":3,"Math":"90","Physics":"90","English":"90"
}
}
]
}, {
"Id":2,"Name":"GB2","Students":[
{
"Id":4,"Name":"Ema","RollNo":"1","Performance":{
"Id":4,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":5,"Name":"Sunny","RollNo":"2","Performance":{
"Id":5,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":6,"Name":"Jen","RollNo":"3","Performance":{
"Id":6,"Math":"90","Physics":"90","English":"90"
}
}
]
}
]
},{
"Id":2,"Name":"Class 2","Location":"Building 1","Groups":[
{
"Id":3,"Name":"G1","Students":[
{
"Id":7,"Name":"Ron","RollNo":"1","Performance":{
"Id":7,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":8,"Name":"Kaka","RollNo":"2","Performance":{
"Id":8,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":9,"Name":"Mark","RollNo":"3","Performance":{
"Id":9,"Math":"90","Physics":"90","English":"90"
}
}
]
}, {
"Id":4,"Name":"G2","Students":[
{
"Id":10,"Name":"Lily","RollNo":"1","Performance":{
"Id":10,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":11,"Name":"Lina","RollNo":"2","Performance":{
"Id":11,"Math":"90","Physics":"70","English":"60"
}
},{
"Id":12,"Name":"Linda","RollNo":"3","Performance":{
"Id":12,"Math":"90","Physics":"90","English":"90"
}
}
]
}
]
}
]