Reputation: 380
I've looked for quite a bit for an answer to this question. Followed documentation on AngularFire 2 and Angular 2 itself but I can't find a working answer. I simply want to delete an entry in my firebase database using the unique key. I could probably do this in Angular 4 but I'm having to do this for Angular 2.
Any support would be greatly appreciated!
import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';
import {Observable} from "rxjs/Observable";
@Component({
selector: 'app-listings',
templateUrl: './listings.component.html',
styleUrls: ['./listings.component.scss']
})
export class ListingsComponent implements OnInit {
items: Observable<any[]>;
item: FirebaseObjectObservable<any[]>;
constructor(db: AngularFireDatabase) {
this.items = db.list('Harry');
this.item = db.object('/Harry/');
}
delete() {
this.item.remove(); // removes all data.
}
ngOnInit() {
}
}
EDIT: Added the HTML
<ul class="list-group">
<li class="list-group-item" *ngFor="let item of items | async">
<p><strong>Name: </strong>{{item.name}}</p>
<p><strong>Email: </strong>{{item.email}}</p>
<p><strong>Mobile: </strong>{{item.mobile}}</p>
<p><strong>Address: </strong>{{item.address}}</p>
<div class="editDel row">
<div class="col-sm-1"><button class="btn-primary">Edit</button></div>
<div class="col-sm-1"><button class="btn-danger" (click)="delete()">Delete</button></div>
</div>
</li>
</ul>
EDIT: Added package versions
{
"name": "ng2-firebase-addresslist",
"version": "0.0.0",
"license": "MIT",
"angular-cli": {},
"scripts": {
"ng": "ng",
"start": "ng serve",
"test": "ng test",
"pree2e": "webdriver-manager update --standalone false --gecko false",
"e2e": "protractor"
},
"private": true,
"dependencies": {
"@angular/common": "^2.3.1",
"@angular/compiler": "^2.3.1",
"@angular/core": "^2.3.1",
"@angular/forms": "^2.3.1",
"@angular/http": "^2.3.1",
"@angular/platform-browser": "^2.3.1",
"@angular/platform-browser-dynamic": "^2.3.1",
"@angular/router": "^3.3.1",
"angular2-flash-messages": "^1.0.8",
"angularfire2": "^2.0.0-beta.7-pre",
"core-js": "^2.4.1",
"firebase": "^3.9.0",
"rxjs": "^5.0.1",
"ts-helpers": "^1.1.1",
"zone.js": "^0.7.2"
},
"devDependencies": {
"@angular/cli": "^1.4.4",
"@angular/compiler-cli": "^2.3.1",
"@types/jasmine": "2.5.38",
"@types/node": "^6.0.42",
"codelyzer": "~2.0.0-beta.1",
"jasmine-core": "2.5.2",
"jasmine-spec-reporter": "2.5.0",
"karma": "1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-remap-istanbul": "^0.2.1",
"protractor": "~4.0.13",
"ts-node": "1.2.1",
"tslint": "^4.3.0",
"typescript": "~2.0.3",
"webpack": "^3.6.0"
}
}
So I've noticed a lot of the guides and tutorials differ wildly on this topic mostly because different versions of AngularFire2 change how this works each time. An issue which has caused a lot of frustration for someone like myself who is learning.
Upvotes: 1
Views: 7388
Reputation: 606
<tbody>
<tr *ngFor='let item of items | async'>
<td>{{item.in}}</td>
<td>{{item.des}}</td>
<td>{{item.cast}}</td>
<td>{{item.tomi}}</td>
<td>{{item.ris}}</td>
<td>
<div class="btn-group">
<button (click)="deleteItem(item)" class= "btn btn-danger"> delete </button>
</div>
<td>
</tr>
</tbody>
**
- .ts file
**
deleteItem(user: User) {
const confirmBox = confirm('Are you sure?');
if (confirmBox) {
this.service.deleteUser(user.id).then(() => {
this.snackBar.open('visitor has been deleted successfully...', 'close');
});
}
}
**
- service
**
constructor(private fireStore: AngularFirestore) { }
deleteUser(id: string): any {
return this.fireStore.doc(`${this.dbName}/` + id).delete();
}
Upvotes: 0
Reputation: 380
So I solved it using a slightly different method.
I noticed posting this in my HTML gave me my individual key for each firebase object.
<p><strong>Item Key: </strong>{{item.$key}}</p>
So I then took it a step further and included it in my onClick function.
<button class="btn-danger" (click)="deleteObject(this.item.$key)">Delete</button>
Which I then fed into my function in listings.components.ts
deleteObject(itemKey) {
this.db.object('/Harry/' + itemKey).remove();
}
That successfully ended up removing the objects by their key one-by-one! Thanks for everyones support here that helped me along the way. Also AngularFire2, get better documentation!!!
Upvotes: 2
Reputation: 23463
Try
items: FirebaseListObservable<any[]>;
delete() {
this.items.remove(this.item)
}
Edit
A couple of other things don't look quite right
constructor(db: AngularFireDatabase) {
this.items = db.list('Harry');
this.item = db.object('/Harry/');
}
should be
constructor(private db: AngularFireDatabase) {
this.items = this.db.list('Harry');
this.item = this.db.object('/Harry/');
}
You may want to also move the code in constructor to Not necessary, according to example linked below.ngOnInit
, as AngularFire might not be ready within the constructor.
Edit #2
The template looks almost ok, but because items
is now FirebaseListObservable
, need to access the iterated item with $value
<p><strong>Name: </strong>{{item.$value.name}}</p>
<p><strong>Email: </strong>{{item.$value.email}}</p>
<p><strong>Mobile: </strong>{{item.$value.mobile}}</p>
<p><strong>Address: </strong>{{item.$value.address}}</p>
Or, use this.items = db.list('Harry').valueChanges()
, as per this example in docs Example of persisting a Document Id
Edit #3
Since you have to use a specific release, I thought it might be useful to take a look at the source for the specific release (https://github.com/angular/angularfire2/releases). 2.0.0-beta.7, although you may have 2.0.0-beta.8.
You may have heard the term 'documentation rots', which means better to look at code and specs when dealing with an older release.
The relevent spec is
describe('remove', () => {
it('should call remove on the underlying ref', () => {
var removeSpy = spyOn(ref, 'remove');
O.subscribe();
O.remove();
expect(removeSpy).toHaveBeenCalledWith();
});
it('should throw an exception if removed when not subscribed', () => {
O = new FirebaseObjectObservable((observer:Observer<any>) => {});
expect(() => {
O.remove();
}).toThrowError('No ref specified for this Observable!')
});
it('should resolve returned thenable when successful', (done:any) => {
O.remove().then(done, done.fail);
});
});
where O
is equivalent to your this.item
. Try is adding this.item.subscribe()
to your delete method.
Also, when you retrieve item, why '/Harry/' and not '/Harry'?
And, you could wrap the operation in a promise to capture errors. From 'docs\2-retrieving-data-as-objects.md',
The promise can be useful to chain multiple operations, catching possible errors from security rules denials, or for debugging.
const promise = af.database.object('/item').remove(); promise.then(_ => console.log('success')) .catch(err => console.log(err, 'You dont have access!'));
Upvotes: 1