0

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.

eat-sleep-code
  • 4,753
  • 13
  • 52
  • 98

2 Answers2

1

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>
  • Where are you getting 'Observable' from? I tried `import {Observable} from 'rxjs/Observable';` but then it says Property 'of' does not exist on type 'typeof Observable' – eat-sleep-code Aug 20 '17 at 23:07
  • 1
    `import { Observable } from 'rxjs/Observable';` and `import 'rxjs/add/observable/of';` – Aleksandr Petrovskij Aug 21 '17 at 09:01
  • Is it possible to further filter the items within the pipeline. I have this: `if (!personId || !type) return Observable.of([]); let output = this.db.list('/event', { query: { orderByChild: 'person', equalTo: personId } }); return output;` Is it possible to further filter "output" so that it only contains items that match the event type? – eat-sleep-code Aug 22 '17 at 05:44
  • 1
    Yes, you can `import 'rxjs/add/operator/map';` and then `return output.map(list => list.filter(value => value.eventType === type))` – Aleksandr Petrovskij Aug 22 '17 at 09:33
  • Thanks! Your input has been accurate and super helpful! – eat-sleep-code Aug 22 '17 at 15:14
0

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.

nGAGE
  • 177
  • 1
  • 11