Requesting a single Firebase object by key from a service

I am using Angular CLI + Firebase + AngularFire2 is trying to figure out how to query a single object from Firebase using a key.

The main thread should be to show a list of items, and then click on an item to display a detailed view for that particular item.

This should be a fairly common use case, but the AngularFire 2 docs don't seem to provide clear examples of how I could do this.

I am trying to use a service to request items, but I cannot get it to work.

Component

// COMPONENT import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router, ActivatedRoute, Params } from '@angular/router'; import { AngularFire, FirebaseObjectObservable} from 'angularfire2'; import { Subscription } from 'rxjs'; import { ItemsService } from '../items.service'; @Component({ selector: 'app-item-detail', templateUrl: './item-detail.component.html', styleUrls: ['./item-detail.component.css'] }) export class ItemDetailComponent implements OnInit, OnDestroy { private subscription: Subscription; private item; constructor(private af: AngularFire, private route: ActivatedRoute, private router: Router, private itemsService: ItemsService) { } ngOnInit() { this.subscription = this.route.params.subscribe( (param: any) => { let id = param['id']; console.log('Key: '+ id); this.item = this.itemsService.getItem(id); } ); } ngOnDestroy() { this.subscription.unsubscribe(); } } 

Service

 import { Injectable } from '@angular/core'; import { Headers, Http, Response } from "@angular/http"; import { AngularFire, FirebaseObjectObservable, FirebaseListObservable, FirebaseApp } from 'angularfire2'; import 'rxjs/Rx'; @Injectable() export class ItemsService { private items: FirebaseListObservable<any[]>; private item: FirebaseObjectObservable<any>; constructor(private af: AngularFire) {} getItems(num) { this.items = this.af.database .list('/items', { query: { limitToLast: num | 20} } ) .map( (arr) => { return arr.reverse() } ) as FirebaseListObservable<any[]>; return this.items; } getItem(id: string) { this.item = this.af.database.object('/items/'+id); this.item.subscribe(item => { console.log(item); return item; }); } } 
+5
source share
1 answer

This should do it:

 // COMPONENT import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router, ActivatedRoute, Params } from '@angular/router'; import { AngularFire, FirebaseObjectObservable} from 'angularfire2'; import { Subscription } from 'rxjs'; import { ItemsService } from '../items.service'; @Component({ selector: 'app-item-detail', templateUrl: './item-detail.component.html', styleUrls: ['./item-detail.component.css'] }) export class ItemDetailComponent implements OnInit, OnDestroy { private subscription: Subscription; private item; constructor(private af: AngularFire, private route: ActivatedRoute, private router: Router, private itemsService: ItemsService) { } ngOnInit() { // get id synchronously, don't need it more then once const key: string; this.route.params.take(1).subscribe(param => key = param["id"]); this.subscription = this.itemsService.getItem(id) .subscribe(item => this.item = item) } ngOnDestroy() { this.subscription.unsubscribe(); } } @Injectable() export class ItemsService { ... getItem(id: string) { return this.af.database.object('/items/'+id); } } 

Try subscribing to Observable where you need data. Your service methods should return Observable, not Subscription (unless you really have a good reason for this).

+2
source

Source: https://habr.com/ru/post/1257947/


All Articles