I've inadvertently changed some code somewhere and now my posts are no longer being pulled through, can anyone spot the mistake?
Service:
posts: AngularFirestoreCollection<any[]>;
constructor(private db: AngularFirestore) { }
getPosts() {
this.posts = this.db.collection('/posts') as AngularFirestoreCollection<any[]>;
return this.posts;
}
}
Post Component:
posts: AngularFirestoreCollection<any>;
constructor(private firebaseService: FirebaseService) { }
ngOnInit() {
this.posts = this.firebaseService.getPosts();
}
}
Post HTML:
<mat-grid-tile *ngFor="let post of posts">
<mat-card class="mat-elevation-z4">
<img mat-card-image src="{{post.imgUrl}}">
<mat-card-actions>
<button mat-icon-button><mat-icon>thumb_up_alt</mat-icon></button><span class="counter mat-small">{{post.numberOfLikes}}</span>
<button mat-icon-button><mat-icon>star</mat-icon></button><span mat-small class="counter mat-small">{{post.numberOfSaves}}</span>
</mat-card-actions>
</mat-card>
</mat-grid-tile>
</mat-grid-list>``
Now I'm getting Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
Here are some suggestions to fix your problem:
AngularFirestoreCollection
should be passed the item type of your collection, here you an array type (any[]
), but something like Post
would be more appropriate.valueChanges()
or snapshotChanges()
on your collection to get an observable of it. this.db.collection('/posts')
only returns a reference to the collection (an object to manage it) and not the list itself.async
pipe in the template to automatically subscribe/unsubscribe from the returned observable.In your service:
export interface Post {
imgUrl: string;
numberOfLikes: number;
numberOfSaves: number;
}
@Injectable()
export class FirebaseService {
postsRef: AngularFirestoreCollection<Post>;
constructor(private db: AngularFirestore) { }
getPosts() {
this.postsRef = this.db.collection('/posts') as AngularFirestoreCollection<Post>;
return this.postsRef.valueChanges();
}
}
In your component:
import { Observable } from 'rxjs';
import { FirebaseService, Post } from '....';
@Component({ ... })
export class MyComponent implements OnInit {
posts$: Observable<Post[]>;
constructor(private firebaseService: FirebaseService) { }
ngOnInit() {
this.posts$ = this.firebaseService.getPosts();
}
}
In your template:
<mat-grid-tile *ngFor="let post of posts$ | async">
...
</mat-grid-list>