eat-sleep-code
eat-sleep-code

Reputation: 4855

Angular4 / AngularFire2: Querying firebase from within a pipe?

Is it possible -- from within a pipe --to query a Firebase database and return a value?

I have the following HTML

<div *ngFor="let item of items">
    <h2>
        {{item.firstName}} {{item.middleName}} {{item.lastName}}
    </h2>

    <div *ngFor="let lifeItem of (item.$key | event: 'life')">
        Born: {{lifeItem.start}}
    </div>
</div>

And the following pipe:

import { Pipe, PipeTransform } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

@Pipe({ 
    name: 'event'
})

export class EventPipe implements PipeTransform {
    subscriptions: Array<any> = new Array<any>();
    items: Array<any> = new Array<any>();
    constructor(
        protected db: AngularFireDatabase
    ){}

    public transform(personId: any, eventType: any) { 
        if (!personId || !eventType) return [];  

        console.info("personId: " + personId);
        console.info("eventType: " + eventType);

        this.subscriptions.push(
            this.db.list('/event', {
                query: {
                    limitToLast: 200
                }
            }).subscribe(items => {
                console.info(items);
                this.items = items;
                return this.items;
            })
        );

    }
}

When I run this, I get this in the console...

enter image description here

... but nothing is rendered in the corresponding section on the page.

Upvotes: 0

Views: 582

Answers (2)

Aleksandr Petrovskij
Aleksandr Petrovskij

Reputation: 1243

I think, it is better to use Angular AsyncPipe

export class EventPipe implements PipeTransform {
    constructor(protected db: AngularFireDatabase){}

    public transform(personId: any, eventType: any) { 
        if (!personId || !eventType) return Observable.of([]);
        return this.db.list('/event', {
            query: {
                limitToLast: 200
            }
        });
    }
}

<div *ngFor="let lifeItem of (item.$key | event: 'life' | async)">
    Born: {{lifeItem.start}}
</div>

Upvotes: 1

nGAGE
nGAGE

Reputation: 177

My guess would be that since the DB call is an async operation, you'll have to account for the delay before the data is available. Try using the async pipe as secondary pipe and null-check before grabbing .items

Something like this: *ngFor="let lifeItem of (item.$key | event: 'life' | async)?.items"

NOTE: I've not tested this code myself. Just making a suggestion.

Upvotes: 0

Related Questions