No $key inside a AngularFireDatabase.object - javascript

In my Angular app I am trying to update records on Firebase database. I am using AngularFireDatabase to first bind the list when then be used to update the particular records. But the problem is that there is no $key.
The app.component.html code is:
<ul>
<li *ngFor="let course of courses">
{{course}}
<button (click)="update(course)">Update</button>
</li>
</ul>
The app.component.ts is:
import { AngularFireDatabase } from 'angularfire2/database';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnDestroy {
courses: any[];
constructor(private db: AngularFireDatabase) {
this.subscription = db.list('/couses').valueChanges().subscribe(c => {
this.courses = c;
});
}
update(course) {
console.log(course.$key);
//gives key undefined
}
}
How to get key so that I can update a particular record?
The snapshot of firebase database is:

I solved the problem using .snapshotChanges() method.
The constructor code becomes:
constructor(private db: AngularFireDatabase) {
this.subscription = db.list('/couses').snapshotChanges().subscribe(c => {
this.courses = c;
});
The update() method:
update(course) {
this.db.list('/couses').set(course.key,"Updated");
}
So Now I am getting the key for doing update of the particular item.
I hope it help, if you have better solution then please have your answer.

Related

How to get ID of collection in Firestore with angular Firestore

I'm not able to get the ID of the document when I query a Firestore Database this way :
Could you give me some help ?
import { Component, OnInit } from '#angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '#angular/fire/firestore';
import { Observable } from 'rxjs';
export interface Item { name: string; }
#Component({
selector: 'app-annonces-contactees',
templateUrl: './annonces-contactees.page.html',
styleUrls: ['./annonces-contactees.page.scss'],
})
export class AnnoncesContacteesPage implements OnInit {
private annoncesCollection: AngularFirestoreCollection<Item>;
annonces: Observable<Item[]>;
constructor(private afs: AngularFirestore) {
this.annoncesCollection = afs.collection('annonces', ref => ref.where('prix', '>=', 1000000))
this.annonces = this.annoncesCollection.valueChanges();
}
ngOnInit() {
}
}
I am going to give you an example of how I dot it:
Let us suppose I have collection of hospitals and each hospital has its name,phone and location.
constructor(private firestore:AngularFirestore){}
hospitalsArray=[];
ngOnInit(){
this.firestore.collection("hospitals").snapshotChanges().subscribe((data) => {
this.hospitalsArray = data.map(e => {
return { id: e.payload.doc.id, location: e.payload.doc.data()["location"], number: e.payload.doc.data()["phone"], name: e.payload.doc.data()["name"]}
})
}
"hospitals" is the name of the collection and this id is the id of the document.
So if you want to display in the html file
<ion-item *ngFor="let hospital of hospitalsArray">
<ion-label>{{hospital.name}}</ion-label>
</ion-item>

Angular #Input() Not Updating UI in Child

I've implemented a child component to render a table based on a list provided via #Input(). The data is loaded via http, however the UI (child component) is not updated unless I wave my mouse over the screen. I've seen people post about implementing ngOnChanges() in my child, but I thought Angular was supposed to do this by default? Am I missing something? Why would the UI not update with this?
Child code looks something like this:
child.component.ts
#Component({
selector: 'child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
})
export class ChildComponent implements {
#Input() data: any[] = [];
constructor() {}
}
child.component.html
<table>
<tr *ngFor="let item of data"><td>{{ item }}</td></tr>
</table>
Parent code that uses the component looks something like this:
parent.component.ts
#Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
data: string[] = [];
constructor(private endpointService: EndpointService) {}
ngOnInit() {
// response is a string array like: ['hello', 'world']
this.endpointService.loadData().subscribe((response) => {
this.data = response;
});
}
}
parent.component.html
<child [data]="data"></child>
============================= EDIT ==================================
I verified that it only fails to load when updating inside of the subscribe callback (if I set a static array, it loads just fine).
So it looks like I'm able to resolve this by running changeDetectorRef.detectChanges() in the parent component, but this feels hackish like I shouldn't have to do this. Is this a good way to resolve this? Or does this indicate something wrong with my implementation?
parent.component.ts
#Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
data: string[] = [];
constructor(private endpointService: EndpointService,
private changeDetectorRef: ChangeDetectorRef) {}
ngOnInit() {
// response is a string array like: ['hello', 'world']
this.endpointService.loadData().subscribe((response) => {
this.data = response;
this.changeDetectorRef.detectChanges();
});
}
}
You can also try to force change detection by forcing the value reference update via, for example, the spread operator:
this.endpointService.loadData().subscribe((response) => {
this.data = [...response];
});
hummm well .. when the component is rendered as first time it will show with the empty array becouse the api call stills happening and needs the onchanges method in child component in order to listen the complete api call and the list will re render
Seems that you have some other errors in template expressions which force the whole template to fail. Here's a stackblitz I've created and everything works: https://stackblitz.com/edit/angular-ivy-w2ptbb?file=src%2Fapp%2Fhello.component.ts
Do you have maybe some errors in console?
I replaced the service with a static string array and it worked well. I think there is problem with the observable subscription.
child.component.ts
import { Component, OnInit,Input } from '#angular/core';
#Component({
selector: 'child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
#Input() data: any[] = [];
constructor() { }
ngOnInit() {
}
}
parent.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css'],
})
export class ParentComponent implements OnInit {
data: string[] = [];
constructor() {}
ngOnInit() {
this.data = ['hello', 'world','aaa','ddd'];
}
}

Can't resolve all parameters for HomeInnerComponent Angular 7

I'm getting the below error in my console when trying to run my Angular application. Here is my html code if you need it https://stackblitz.com/edit/angular-xrbrjq?file=src%2Fapp%2Fapp.component.html
Error: Can't resolve all parameters for HomeInnerComponent: (?).
Please have a look below for my component details.
Home-inner.component.ts:
import { Component, OnInit } from '#angular/core';
import {CategoriesService } from '../../Admin/categories/categories.service';
import {Categories } from '../../Admin/categories/categories';
#Component({
selector: 'app-home-inner',
templateUrl: './home-inner.component.html',
styleUrls: ['./home-inner.component.css']
})
export class HomeInnerComponent implements OnInit {
leftCat:Categories;
constructor(private leftCategoriesService: CategoriesService) { }
ngOnInit() {
// For showing category list in the left side
this.leftCategoriesService.getCategories()
.subscribe((data: any) => {
this.leftCat = data;
//console.log(this.leftCat);
// localStorage.removeItem('editEmpId');
});
// Left side category list ends here
}
}

How to manage list among components in angular 4

I have a BookingSearch component.
//imports
#Component({
selector: 'booking-search',
templateUrl: './booking-search.component.html',
styleUrls: ['./booking-search.component.css']
})
export class BookingSearchComponent implements OnInit {
constructor(private bookingRetrieveService: BookingRetrieveService,
private bookingTreeService: BookingTreeService) {
}
ngOnInit() { }
loadBooking() {
this.bookingRetrieveService.retrieveBooking(bookingId, firstName, lastName)
.subscribe(
response => {
let openBookingUrl = '/booking?b=' + this.bookingId;
window.open(openBookingUrl, '_self');
},
error => { }
);
}
}
Once the booking is loaded it needs to add into a booking tree and page redireds to BookingDetail component.
#Injectable()
export class BookingTreeService {
constructor() { }
addBooking(booking) { }
}
This booking tree needs to be used in a BookingDetail component.
#Component({
moduleId: module.id,
selector: 'booking-detail',
templateUrl: 'booking-detail.component.html',
styleUrls: ['booking-detail.component.css']
})
export class BookingDetailComponent implements OnInit {
booking: any = {};
constructor(private bookingService: BookingTreeService) {
}
ngOnInit() {
//how to get updated booking tree here
}
}
How to update booking tree when search new booking and how can it be used in BookingDetailComponent.
Any suggestions are appreciated.
Thank You!
You can store the booking tree inside a service and access it from your booking-details component.
Like:
#Injectable()
export class BookingTreeService {
bookingTree: Booking[] = [];
constructor() { }
addBooking(booking) {
this.bookingTree.push(booking);
}
}
Then in your bookingDetails component:
constructor(private bookingService: BookingTreeService) {
this.bookings = this.bookingService.bookingTree;
}

Angular Firebase Querying?

This is my .ts file to query the angular firebase database
import { Component, OnInit } from '#angular/core';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database';
#Component({
selector: 'app-candidate-reg-success',
templateUrl: './candidate-reg-success.component.html',
styleUrls: ['./candidate-reg-success.component.css']
})
export class CandidateRegSuccessComponent implements OnInit {
result:any;
items: FirebaseListObservable<any[]>;
constructor(db: AngularFireDatabase) {
debugger;
this.items=db.list('/candidates_list',{
query:{
orderByChild:'email',
equalTo:'pranavkeke#gmail.com'
}
});
this.items.subscribe(quiredItems=>{
this.result=quiredItems;
console.log(this.result);
console.log(this.result.FirstName);
// console.log();
});
// debugger;
// const rootRef=firebase.database().ref();
// const mail=rootRef.child('candidates_list').orderByChild('email').equalTo('pranavkeke#gmail.com');
// console.log(mail);
}
ngOnInit() {
}
}
I am getting the user with specified criteria, but I want only the firstname of the user.The problem is with this one
console.log(this.result.FirstName);
The result variable holds all the json data from firebase, butI want only firstname. But in console it shows undefined. How can be it solved? Please help me. Thanks in advance.
try to transform each item in the FirebaseListObservable first:
this.items=db.list('/candidates_list',{
query:{
orderByChild:'email',
equalTo:'pranavkeke#gmail.com'
}})
.map(item => item.FirstName) as FirebaseListObservable<any[]>;

Categories