Angular ngFor cannot render entire data - javascript

I fetch data from api by resolver before loading component, also can see whole data in console and {{ data.length }} prints correct 100 number as well, but ngFor renders random amount of data about 20
// data.component.ts
data: BooksData[];
ngOnInit(): void{
this.route.data.subscribe(
data => {
console.log(data) // prints entire data correctly, data: Array(100)
this.data = data;
}
)
}
{{ data.length }} <!-- 100 -->
<ul>
<li *ngFor="let d of data">{{ d.title }}</li>
</ul>
i also tried slice pipe *ngFor="let d of data | slice:0:(data.length-1)" but same result

You have syntax problem in the interpolation of data.title
{{ data.length }} <!-- 100 -->
<ul>
<li *ngFor="let d of data">{{ data.title }}</li>
</ul>
Should be
{{ data.length }} <!-- 100 -->
<ul>
<li *ngFor="let d of data">{{ d.title }}</li>
</ul>

Syntax issue data.title should be d.title
.html:
<ul>
<li *ngFor="let d of data | async">{{ d.title }}</li>
</ul>

You already know now what is the problem from above comments.
i.e data.tile need to changed to d.title
If you want you can use below more readable code
books$: BooksData[];
ngOnInit(): void{
this.books$ = this.route.data;
}
In html
<ul *ngIf="books$ | async as books">
<li *ngFor="let book of books">
{{ book.title }}
</li>
</ul>

Related

document.querySelector in Angular

I have a list where each li has unique data-id.
<ul class="list">
<li class="list__el"
*ngFor="let item of cars"
data-id="{{ item.id }}">
</li>
</ul>
In JS I would wrote
let myLi = document.querySelector(`.list__el[data-id="${item.id}"]`)
How to correctly rewrite it for Angular?
Use #ViewChildren and a template reference such as #listItem.
#Component({
template: `<ul class="list">
<li #listItem class="list__el"
*ngFor="let item of cars"
data-id="{{ item.id }}">
</li>
</ul>`
})
export component MyComponent implements AfterViewInit {
// Note that the parameter here relates to the #listItem in the template.
#ViewChildren('listItem')
public listItems!: QueryList<ElementRef<HTMLLIElement>>
public ngAfterViewInit() {
console.log(
this.listItems.find(itm =>
itm.nativeElement.getAttribute('data-id') === 'my-element-id'
)
)
}
}

2d array in Vue.js

I'm fairly new to Vue and js and I'm trying to create a Todo App with firebase integration.
What i need it to look like is the following: there should be an option to create a new list of tasks and an option to create new tasks within this list.
So i need a list of lists.
My firebase database structure looks like this:
users (collection) -> tasks(collection) -> and inside the followin structure:
I understand that there should be a nested v-for element right?
Something like this:
<div v-for="task in tasks" :key="task.id">
<ul v-for="todo in task(?)">
</ul>
</div>
But i don't understand how to approach it.
Any advice will be GREATLY appreciated!
<template>
<ul>
<li v-for="task in tasks" :key="task.id">
{{task.name}}
<ul>
<li v-for="td in task.todo" :key="td.id">
{{ td.completed }}
<br>
{{ td.date }}
<br>
{{ td.title }}
<br>
{{ tdurgent }}
</li>
</ul>
</li>
</ul>
</template>
<script>
import {db} from './firebase';
export default {
data() {
return {
users: {}
}
},
firebase: {
tasks: {
source: db.ref('tasks'),
// Optional, allows you to handle any errors.
cancelCallback(err) {
console.error(err);
}
}
}
}
</script>
firebase.js
import Firebase from 'firebase'
const firebaseApp = Firebase.initializeApp({
// Populate your firebase configuration data here.
...
});
// Export the database for components to use.
// If you want to get fancy, use mixins or provide / inject to avoid redundant imports.
export const db = firebaseApp.database();
You can write like this
<div v-for="task in tasks" :key="task.id">
<ul v-for="todo in task.keyOfArrayType" :key="todo.id" >
{{todo.name}}
</ul>
</div>
In the json no key id display for both outer and inner if you interested to put key:="task.id" then you have to change the structure like
otherwise remove :key = "task.id" and :key="td.id"
<ul>
<li v-for="task in tasks" :key="task.id">
{{name}}
<ul>
<li v-for="td in task.todo" :key="td.id">
{{ completed }}
<br>
{{ date }}
<br>
{{ title }}
<br>
{{ urgent }}
</li>
</ul>
</li>
</ul>

Angular ngfor loop displaying menu

I am trying create a menu and sub menu.. The structure I want for my menu is mentioned below. Here is the demo I am trying I am getting wrong structure.
Demo https://stackblitz.com/edit/angular-odvcsm.
"Sub Test": { // Main menu
"Example1":"hai",//sub menu
"Ex2":"hello"// sub menu
},
You need one more level of iteration here to go down in the sub-menu and to remove the top level label as it's no use for your case:
HTML
<ul *ngFor="let partner of list_value | keyvalue let i=index">
<li *ngFor="let innerData of partner.value | keyvalue">
<ul class="submenu">
<li *ngFor="let innerData1 of innerData.value | keyvalue">
{{innerData1.key}}
<ul class="submenu">
<li *ngFor="let item of innerData1.value | keyvalue">
{{item.value}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
demo

How to do multiple filters on click event in Angular.Js?

I am showing different articles from the JSON file and I want to filter the articles based on "Category", "Locations", "date". So If I select any category then the result should filtered out based on the specific category and then if I select location then result should be filtered out based on category and location. Please check my running code here "http://plnkr.co/edit/1vcIAPSwvxQcbIzMhyzp?p=preview"
Please check my code html code:
<div ng-controller="ListCtrl">
<h2>By Category</h2>
<ul >
<li ng-repeat="category in categories | filter:{parent: 0}:true | uniqueCategoryFilter">{{category.id}} - {{category.title}} - {{category.parent}}</li>
</ul>
</div>
<div ng-controller="ListCtrl">
<h2>By Location</h2>
<ul >
<li ng-repeat="location in taxonomy_location | uniqueLocationFilter">{{location.title}}</li>
</ul>
</div>
<div ng-controller="ListCtrl">
<h2>By Date</h2>
<ul >
<li ng-repeat="article in posts">{{article.date}}</li>
</ul>
</div>
<div ng-controller="ListCtrl">
<ul ng-repeat="article in posts">
<li><img src="{{article.thumbnail}}" /><h2>{{article.title}}</h2><span >{{article.date | date:'mm/dd/yyyy'}}</span></li>
</ul>
Please check my javascript code here:
function ListCtrl($scope, $http) {
$http({
method: 'GET',
url: 'json_price_1.json'
}).success(function(data) {
$scope.posts = data.posts; // response data
$scope.categories = [];
$scope.taxonomy_location = [];
angular.forEach(data.posts, function(article, index) {
angular.forEach(article.categories, function(category, index){
$scope.categories.push(category);
});
angular.forEach(article.taxonomy_location, function(location, index){
$scope.taxonomy_location.push(location);
});
});
});
}

Get the index (counter) of an 'ng-repeat' item with AngularJS?

I am using AngularJS and its ng-repeat directive to display a sequence of questions. I need to number each question starting with 1. How do I display and increment such a counter with ng-repeat? Here is what I have so far:
<ul>
<li ng-repeat="question in questions | filter: {questionTypesId: questionType, selected: true}">
<div>
<span class="name">
{{ question.questionText }}
</span>
</div>
<ul>
<li ng-repeat="answer in question.answers">
<span class="name">
{{answer.selector}}. {{ answer.answerText }}
</span>
</li>
</ul>
</li>
</ul>
Angularjs documentation is full of examples, you just need to take some time and explore it.
See this example here : ngRepeat example , it's the same case.
<ul>
<li ng-repeat="question in questions | filter: {questionTypesId: questionType, selected: true}">
<div>
<span class="name">
{{$index + 1}} {{ question.questionText }}
</span>
</div>
<ul>
<li ng-repeat="answer in question.answers">
<span class="name">
{{answer.selector}}. {{ answer.answerText }}
</span>
</li>
</ul>
</li>
</ul>
Reached here by searching for something similar.
Here is what worked for me.
{{$index + 1}}
+1 is added because the index starts from 0.
There are two ways to get an index for the given array in ng-repeat
Using $index
<th ng-repeat="n in [].constructor(3 + 1) track by $index">{{$index}}</th>
Using a counter
This method is useful when you have nested ng-repeat and you need counters for both loops...the following example uses counter row. Although track by $index is required, it is not used for the logic.
<tr ng-repeat="(row, y) in getNumber(h.seats.length, 3) track by $index">
<td>{{row+1}}</td>
In both cases counter starts with 0 and you can offset using +1 if you like

Categories