I am using firebase realtime database in angular. I am trying to get some data from firebase server in realtime: (Code from a service)
getData(child){
return firebase.database().ref(child).on('value', (snapshot) => {
console.log(snapshot.val())
})
}
and subscribing to above function in my component:
this.examinerService.getData('batches/names').subscribe(
(batches) => {
this.batches = batches.val();
}
)
Which is giving me error:
Property 'subscribe' does not exist on type '(a: DataSnapshot, b?: string) => any'
I have tried using ref().once()
which works fine but I want realtime behavior.
Update:
Currently I am using database().ref().on('value', (snapshots) => { console.log(snapshots.val()); });
in my component which works fine but I want to do it inside my service and subscribe to it in my components. Someone told me that its not an observable so you can't subscribe to it. I am new to angular so I don't know how to make an observable and bind snapshots with it.
child(busNum). exists() tests for the existence of a value at location BusNumber/<busNum> . It will not be true unless busNum is one of the keys created by push() .
A DataSnapshot contains data from a Database location. Any time you read data from the Database, you receive the data as a DataSnapshot . A DataSnapshot is passed to the event callbacks you attach with on() or once() . You can extract the contents of the snapshot as a JavaScript object by calling the val() method.
The API docs for child() says: Gets a Reference for the location at the specified relative path. The method is helping you build a path to a reference. Without the call to child() in your second example, the reference will be at the root of the database, rather than under "/posts".
The function getData
is returning the passed callback instead of an Observable
which is what the code seems to be expecting. You can modify the function as such in order to return an Observable
that you can .subscribe()
to.
import { Observable } from 'rxjs/Observable';
getData(child) {
return Observable.create(subscriber => {
const ref = firebase.database().ref(child);
const callbackFn = ref.on('value',
// emit a value from the Observable when firebase data changes
(snapshot) => subscriber.next(snapshot.val()),
// error out the Observable if there is an error
// such as permission denied
error => subscriber.error(error)
);
// The function passed to Observable.create can return a callback function
// which will be called when the observable we created is unsubscribed from.
// Just as we used `ref.on()` previously our callback function calls `ref.off`
// to tell firebase that we are no longer interested in the changes
return () => ref.off('value', callbackFn);
});
}
Let's say our data structure looks something like this
{
batches: {
names: [
{
first: 'FirstName',
last: 'LastName'
},
{
first: 'FirstName1',
last: 'LastName1'
}
]
}
}
For name we might have an interface that looks like this
export interface Name { first: string; last: string; }
Then we have a service that looks something like this
import { Injectable } from '@angular/core';
import { Name } from "./name";
import { AngularFireDatabase, AngularFireList } from "angularfire2";
@Injectable()
export class NameService {
constructor(private db:AngularFireDatabase) { }
getAllNames(): AngularFireList<Name> {
return this.db.list('batch/name');
}
}
Last our component can look something like this
import { Component, OnInit } from '@angular/core'
import { AngularFireList } from "angularfire2";
@Component({
selector: 'app-name-list',
template: `
<div *ngFor="let name of names$">
{{ name.last }}, {{ name.first }}
</div>
`
})
export class NameListComponent implements OnInit {
names$: AngularFireList<Name>;
constructor(private nameService: NameService) {}
ngOnInit() {
this.names$ = nameService.getAllNames();
}
}
Angular uses websockets to update in realtime. I am not sure but I think this might be the behavior you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With