how to display data with *ngFor - html

i trying to display data with *ngFor, but for some reason this doesn't display any data, and any error.
I already tried alot of samples that i found in internet, none of those worked so i decide to ask here.
here is what i have:
ts file:
public querySuccess: any[];
this.userService.getMentions().subscribe(
(returnAPI) => {
this.querySuccess = returnAPI.data;
});
my html:
<div *ngIf="returnAPI">
<div *ngFor="let key of querySuccess">
<div>{{querySuccess.firstName}}</div>
</div>
</div>
<div *ngIf="!returnAPI">
<div>0 results found!</div>
</div>
the getMentions().subscribe() return this Json:
{
total: 3,
data:[
{userId: 0, firstName: "test", lastName: "xzy"},
{userId: 0, firstName: "john", lastName: "yeet"},
{userId: 0, firstName: "jamal", lastName: "abc"}]
}

You don't need that if condition to loop that ngFor.If its to show that no data error message use querySuccess because returnAPI does not seems to defined anywhere.
<div *ngIf="querySuccess">
<div *ngFor="let key of querySuccess">
<div>{{key.firstName}}</div>//key is single istance queryselector is full array.
</div>
</div>
<div *ngIf="!querySuccess">
<div>0 results found!</div>
</div>

you can try like this
<div *ngIf="returnAPI">
<div *ngFor="let key of querySuccess">
<div>{{key.firstName}}</div> <!-- key instead of querySuccess -->
</div>
</div>

Hi i would firstly recommend you put your code in a function like
ngOnInit() {
this.getAllQueries();
}
getAllQueries() {
this.userService.getMentions().subscribe(
(returnAPI) => {
this.querySuccess = returnAPI.data;
return this.querySuccess;
});
}
make sure you call this in the ngOninit function or your constructor

Related

Angular NgFor Path Issue

In my Angular Application I have a simple ngFor loop showing logo images like this:
<div *ngFor="let item of list" class="logo-wrapper">
<div class="customer-logo">
<span
class="my-icon"
aria-label="My icon"
[inlineSVG]="'./assets/image/projects/logo/' + item.logo">
</span>
</div>
</div>
This is working fine!
But: If I try to slice the Array to limit the output as follow:
<div *ngFor="let item of list | slice: 0:10; let i = index" class="logo-wrapper">
<div class="customer-logo">
<span
class="my-icon"
aria-label="My icon"
[inlineSVG]="'./assets/image/projects/logo/' + item.logo">
</span>
</div>
</div>
I get this Error : "Object is of type 'unknown'".
Error output:
I really don't know what I'm doing wrong here. I hope someone can point me in the right direction.
Edit: The problem appears as soon as I add a index to the loop.
I tried to add the index to the object like: item.i.logo but its also unknown.
PS: Here is my .ts-file
#Component({
selector: 'app-logo-section',
templateUrl: './logo-section.component.html',
styleUrls: ['./logo-section.component.scss']
})
export class LogoSectionComponent implements OnInit {
list : any
constructor()
{
this.list = getProjects()
console.log(this.list)
}
ngOnInit(): void
{
}
private services = [{
slug : "s-l-u-g",
name : "name",
work : "work",
company : "company",
website : "https://www.google.com",
preview : "text",
logo : "logo.svg"
}]
getProjects()
{
return services
}
}
You would have to change the type of list to any[] instead of any. Update the declaration as follows in your typescript file.
list : any[];
It seems like the SlicePipe deprecates with the ng-inline-svg package because it uses HttpClientModule and works asynchronously.
if you use Array.slice method instead of the SlicePipe in the *ngFor it works fine.
Please find the Stackblitz example.
<div *ngFor="let item of list.slice(0, 10); let i = index" class="logo-wrapper">
<div class="customer-logo">
<span class="my-icon" aria-label="My icon" [inlineSVG]="item.logo"> </span>
</div>
</div>

Property 'name' does not exist on type 'string' ngFor in Angular

I got this error while trying to display an array of objects
Error: src/app/components/timeline/timeline.component.html:9:29 - error TS2339: Property 'name' does not exist on type 'string'.
<h4>{{publication.user.name}}</h4>
~~~~
src/app/components/timeline/timeline.component.ts:10:15
10 templateUrl: './timeline.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component TimelineComponent.
in my timeline.component.html I have this:
<div id="publications">
<div *ngFor = "let publication of publications" class="item-publication">
<div class="panel panel-default">
<div class="panel-body">
<h4>{{publication.user.name}}</h4>
</div>
</div>
</div>
</div>
and this is the getPublications function that I have
getPublications(page){
this._publicationService.getPublications(this.token, page).subscribe(
response => {
console.log(response);
if(response.publications){
this.total = response.total_items;
this.pages = response.pages;
this.publications = response.publications;
if(page > this.pages){
this._router.navigate(['/home']);
}
}else{
this.status= 'error';
}
},
error =>{
var errorMessage = <any>error;
console.log(errorMessage);
if(errorMessage != null){
this.status = 'error';
}
}
);
}
If I make a console.log(response) it shows me the values of the array and the properties are correct (name,surname,email, text etc)
In the HTML code, when I do the loop for the publication's text <h4>{{publication.text}}</h4> it works and even if I use <h4>{{publication.user}}</h4> it shows a list of Objects.
I'm taking an online course and basically copying what the teacher does line by line but IDK why when I try to display name and surname properties, it shows the error that I told you
Thank you for your help.
I found the solution and is related to TS type system so basically I have a model object called publication.ts which includes:
export class Publication{
constructor(
public _id:string,
public text: String,
public file: String,
public created_at: String,
public user: String
){}
}
And the issue was related to the type for the property user so by changing its type to public user: any it worked and now it shows the required fields. Sorry for posting this without a deep search before ask for help. Newbie mistakes
Thanks for the help
You are subscribing to the data so there is a small delay in getting the data. Wrap the tag with a *ngIf to wait for the data to be available.
<div *ngIf="publications" id="publications">
<div *ngFor = "let publication of publications" class="item-publication">
<div class="panel panel-default">
<div class="panel-body">
<h4 *ngIf="publication && publication.user && publication.user.name">{{publication.user.name}}</h4>
</div>
</div>
</div>
</div>

when using a GET method data is coming in console not in HTML

I have written my get method inside ngOnInIt(). When I am printing data in console it is visible, but when printing in HTML using interpolation, it is returning [ object object]
{{filteredCourses}} ==> [object object]
and when i am using {{course.category|json}} so here i am getting all values of array ["course" : "database" , "category" : "database" , "length" : "2hr" ] thats how the value is coming
html :-
<div class="courses" fxLayout="row wrap" fxLayoutAlign="center" [#animateStagger]="{value:'50'}">
<div class="course" *ngFor="let course of filteredCourses" fxFlex="100" fxFlex.gt-xs="50"
fxFlex.gt-sm="33" [ngClass]="course.category" [#animate]="{value:'*',params:{y:'100%'}}">
<div class="course-content" fxLayout="column" fxFlex="1 1 auto">
<div class="header" fxLayout="row" fxLayoutAlign="center center"
[ngClass]="course.category + '-bg'">
<div class="category" fxFlex>
{{course.category|json}}
</div>
</div>
</div>
Code:
filteredCourses: any[];
this.product_name = getProduct()['name'];
console.log(this.product_name);
this.token = getToken();
this.httpHeaders = new HttpHeaders({ "Authorization": "Bearer " + this.token });
this._httpClient.get('http://127.0.0.1:8000/api/products/info/'+this.product_name+'/',{headers: this.httpHeaders})
.subscribe(
data => {
this.product = data;
this.courses = data['cources'];
this.filteredCourses = this.courses;
console.log(this.filteredCourses);
},
error => {
console.log(error);
}
);
try using JSON.stringify(yourObject) or maybe in certain cases you can use Object.keys().
You need to use loop if its an array of object or you might want to print the properties of object individually.
But if you want to see the object filteredCourses in template, use json pipe.
{{filteredCourses | json}}
In case you need help to print values using *ngFor or properties, do let us know.
I suppose filteredCourses collection contains an array of objects. So you need to iterate through filteredCourses using ngFor directive to render data in the HTML template.
Like:
<ul>
<li ngFor="let item of filteredCourses">{{item.courseName}}</li>
</ul>

Access nested json object angular 6

I'm trying to access the nested data from the HTML template, but I get undefined or I get nothing as result (empty page with no class list or student list).
The HTML template:
<div class="container">
<label *ngFor="let class of listClass | keyvalue">
<span> {{class.value.name}} </span>
</label>
<div>
<label *ngFor="let student of class.students | keyvalue">
<span>{{student.value.fullName}} </span>
</label>
</div>
</div>
This is the fonction that gets the list of class and the students in it:
getListClasseStudent(){
this.classService.getStudents().subscribe((data) => {
this.listClass = data;
});
}
The nested data:
class:
0:{
code: "Math01"
teacher:
0: {id: 17551, name "Jack"}
students:
0: {studentId: 1, fullName: "Patrick bob"}
1: {studentId: 2, fullName: "Alice Alice"}
}
1:{
code: "English01"
teacher:
0: {id: 2, name "Nicolas"}
students:
0: {studentId: 1, fullName: "Patrick bob"}
1: {studentId: 2, fullName: "Alice Alice"}
}
I want to access to the list of student of each class, is there any efficient way to do it? thanks in advance.
<div class="container">
<div *ngFor="let c of listClass ">
<label >
<span> {{c.code}} </span>
</label>
<div>
<label *ngFor="let student of c.students ">
<span>{{student.fullName}} </span>
</label>
</div>
</div>
Try this (example without your pipe)
A 'Class' object don't have a attribute 'value.name' (probably gonna be injected by your pipe '| keyvalue' ).
Second *ngFor need t be inside of first, because he need's to iterate a students array, inside each class.
I hope this helps.
create a pipe like below
import { Pipe, PipeTransform } from "#angular/core";
#Pipe({ name: 'ObjNgFor', pure: false })
export class ObjNgFor implements PipeTransform {
transform(value: Object): Array<string> { return Object.keys(value); }
}
import the above pipe in app.module.ts and use pipe in the html page like below
<div *ngFor="let key of questions | ObjNgFor" class="row">
{{ questions[key].name}}
<div *ngFor="let r of questions[key].sub_sections | ObjNgFor ; let indx=index"
class="card-body">
{{ questions[key].sub_sections[r].name }}"
</div>
This example should work

How to display an object's variable's name in HTML?

I seem to be repeating myself when building a detail class to display object data. Is there a way to *ngFor: for each attribute of the rug object, display the attribute's name, and then bind it to the object's value?
//rug-detail.component.ts
<div class="row">
<div class="col-md-3">Name:</div>
<div class="col-md-6">{{rug.name}}</div>
</div>
<div class="row">
<div class="col-md-3">ID:</div>
<div class="col-md-6">{{rug.id}}</div>
</div>
<div class="row">
<div class="col-md-3">Availability:</div>
<div class="col-md-6">{{rug.availability}}</div>
</div>
<div class="row">
<div class="col-md-3">Price:</div>
<div class="col-md-6">{{rug.price|currency:"USD":"symbol"}}</div>
//rug.ts
export interface Rug{
name: string;
id: number;
availability: String;
price: number;
}
The same question, for Ruby: Accessing a variable's name from an object
A hint:
rug = {
name: "Name",
id: 42,
availability: "in stock",
price: 123,
};
for (const key in rug) {
console.log(`${key}: ${rug[key]}`)
}
// OR
for (const key of Object.keys(rug)) {
console.log(`${key}: ${rug[key]}`)
}
One of the two must be usable in Angular's *ngFor