I am trying to test for an object to exist in my AngularFire table. I am having issues returning the subject to detect if the file exists or not.
/**
* Check if the Id exists in storage
* @param Id string | number Key value to check
* @returns Subject<boolean>
*/
public Exists(Id:string):Subject<boolean> {
const Status$:Subject<boolean> = new Subject<boolean>();
let RecordExists:boolean = false;
this.AfDb_.object<T>(`_Testing_/${Id}`).valueChanges()
.subscribe( (OneRecord:T) => {
if (OneRecord.Key_ !== undefined && OneRecord.Key_ !== null && OneRecord.Key_.length > 0) {
RecordExists = true;
}
})
;
Status$.next(RecordExists);
return Status$;
}
This is always returning undefined. My automated tests then fail as well.
it('should confirm a record exists in storage', fakeAsync( () => {
let Exists:boolean;
const Status$:Subject<boolean> = ServiceUnderTest.Exists('Good'); // This exists in Firebase
Status$.subscribe( (Result:boolean) => {
Exists = Result;
});
flushMicrotasks();
Status$.unsubscribe();
expect(Exists).toBeTrue();
}));
I have access in Firebase to /Testing/Good which is an object with a structure of Key_ and Name.
Modules from package.json
"@angular/fire": "^5.4.2",
"firebase": "^7.9.3",
However, if I simply try to return a result without going directly to AngularFire, these tests work.
public Exists(Id:string):BehaviorSubject<boolean> {
const Status:BehaviorSubject<boolean | undefined> = new BehaviorSubject<boolean | undefined>(undefined);
Status.next(true);
return Status;
}
You have to call next
on subject when RecordExists
came from .valueChanges()
e.g.:
let RecordExists:boolean = false;
this.AfDb_.object<T>(`_Testing_/${Id}`).valueChanges()
.subscribe( (OneRecord:T) => {
if (OneRecord.Key_ !== undefined && OneRecord.Key_ !== null && OneRecord.Key_.length > 0) {
Status$.next(true);
} else {
Status$.next(false);
}
})
;
return Status$;
Your code behave in different way in test and simple example because both are call this .valueChanges()
in synchronous way so .next()
is called after subscribe
. In real life valueChanges is async so subscribe
is called before next
.
====================Edited=====================
to connect with real database you have to modify your test to be async (because connection is async:
it('should confirm a record exists in storage',((done) => {
Status$.subscribe( (Result:boolean) => {
expect(Exists).toBeTrue();
done()
});
d}))