Hi everyone, I am trying to display data from a referenced node in firebase and it did not seem to work well for me.
In firebase i have two nodes, applicants and students

This is my code in compent
import { Component, OnInit } from '@angular/core';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
@Component({
selector: 'app-students',
templateUrl: './students.component.html',
styleUrls: ['./students.component.css']
})
export class StudentsComponent implements OnInit {
students: Array<any> = [];
final_data: Array<any> = [];
loading: boolean = true;
constructor(private af: AngularFire) {
af.database.list('/students', {
}).subscribe(res => {
this.students = res;
this.final_data = this.students.map(function (key) {
return af.database.list('/applicants/' + `${key.$key}`);
});
this.loading = false;
});
}
ngOnInit() {
}
}
And this is my code in template
{{final_data}}
<section class="contacto-main">
<div class="container cont">
<div *ngFor="let user of final_data">
<b>{{user.name}}</b><br>
</div>
</div>
</section>
the result

Any help?
Thanks a lot
It looks like you are using a list when you don't want to be for that second database call. You should be using the object in this case. You are getting 14 lists instead of 14 objects. So your code should read
af.database.list('/students', {
}).subscribe(res => {
this.students = res;
this.final_data = this.students.map(function (key) {
return af.database.object('/applicants/' + `${key.$key}`);
});
this.loading = false;
});
}
And if I'm not mistaken, your template should make use of the async pipe since that data won't be available immediately. You're template should then be:
<section class="contacto-main">
<div class="container cont">
<div *ngFor="let user of final_data">
<b>{{(user | async)?.name}}</b><br>
</div>
</div>
</section>
Honestly when I am querying 2 parts of the database and I need both pieces of data before I can display anything I start looking at some observable combinators to help with that type of issue. This would let you get data from both places and combine them into 1 observable without subscribing outside of a single async pipe in your template. It results in a little bit cleaner code I find, but it's up to you. In your case you need the list of students and then you use that list to get the info from the other node. You might try using combineLatest or zip, depending on how your data gets updated in the database.
Edit: Formatting was stupid
I am not understanding your point very clearly, you would have some example code of the solution that you propose
@atinybeardedman Hi, As your upper comment can we do that with items: FirebaseListObservable
work with arrayItems:Array
export class AppComponent {
items: FirebaseListObservable<any>;
wathlist: FirebaseListObservable<any>;
arrayItems: Array<any> = [];
arrayWathlist: Array<any> = [];
newSubject: Subject<any>;
constructor(db: AngularFireDatabase) {
// this.items = db.list('/ktmarket');
// this.items.subscribe(element => {
// console.log(element);
// });
// this.wathlist = db.list('/watchlist');
// this.wathlist.subscribe(element => {
// console.log(element);
// });
db.list('/watchlist', {
}).subscribe(res => {
this.arrayWathlist = res;
this.arrayItems = this.arrayWathlist.map(function (key) {
return db.object('/ktmarket/' + `${key.$value}`);
// console.log(`${key.$value}`);
});
// this.loading = false;
});
console.log(this.arrayItems);
}
The solution is print in template as async
and retriev data as a object
Thanks
<div *ngFor="let user of final_data">
<b>{{(user | async)?.name}} </b><br>
</div>
af.database.list('/students', {
}).subscribe(res => {
this.students = res;
this.final_data = this.students.map(function (key) {
return af.database.object('/applicants/' +${key.$key});
});
this.loading = false;
});
Hi all,
I am trying to read the attribute of an object like the way specified above but I'm getting an error: Cannot read property dateCreated of null.
I was going to ask this question here but then I solved it so I'm writing the solution here. You can correct me if you want.
I solved the error by doing the following
<h5>Complaint Submitted on: {{ hello(item | async) }}</h5>
and in my typescript file:
hello(item) {
if(item != null) {
return item.dateCreated;
}
}
HI, Someone can help me please ?
https://stackoverflow.com/questions/50931526/display-data-from-firebase-with-angularfire2
Most helpful comment
It looks like you are using a list when you don't want to be for that second database call. You should be using the object in this case. You are getting 14 lists instead of 14 objects. So your code should read
And if I'm not mistaken, your template should make use of the async pipe since that data won't be available immediately. You're template should then be:
Honestly when I am querying 2 parts of the database and I need both pieces of data before I can display anything I start looking at some observable combinators to help with that type of issue. This would let you get data from both places and combine them into 1 observable without subscribing outside of a single async pipe in your template. It results in a little bit cleaner code I find, but it's up to you. In your case you need the list of students and then you use that list to get the info from the other node. You might try using combineLatest or zip, depending on how your data gets updated in the database.
Edit: Formatting was stupid