I am attempting to get the values of a BehaviorSubject. The values are returned but how to i utilized them to use them in a return true/false statement.
BehaviorSubject {_isScalar: false, observers: Array(0), closed: false, isStopped: false, hasError: false, …}
closed:false
hasError:false
isStopped:false
observers:[Subscriber]
thrownError:null
value:(...)
_isScalar:false
_value:Array(3)
0:"[email protected]"
1:"Bob Smith"
2:{adminUser: false, basicUser: true} length:3
__proto__:Array(0)
__proto__:Subject
My Behavior Subject has the following being sent to it. Why am i getting null at the start.
user: BehaviorSubject<User> = new BehaviorSubject<User>(null);
// The behavior-roles of the user.
this.afAuth.authState
.switchMap(auth => {
if (auth) {
/// signed in
const authData = this.db.list<User>('users/' + auth.uid).valueChanges();
console.log(authData);
return this.db.list<User>('users/' + auth.uid).valueChanges();
} else {
/// not signed in
return Observable.of(null);
}
})
// .subscribe(console.log); // check the subscription
.subscribe((userData) => {
console.log(userData);
this.user.next(userData);
// this.user.next(user);
// console.log(this.user.next(userData));
});
}
The results i am having issues with:
Check Value false authguard.service.ts:39
Route was False authguard.service.ts:26
Check Value true
I run console.log and the value shows up null first therefore has a false response. Then it runs again and becomes true. This all happens after running the page initially. I need for my check value to be true on load.
I am attempting to get the values of a BehaviorSubject. The values are returned but how to i utilized them to use them in a return true/false statement.
BehaviorSubject {_isScalar: false, observers: Array(0), closed: false, isStopped: false, hasError: false, …}
closed:false
hasError:false
isStopped:false
observers:[Subscriber]
thrownError:null
value:(...)
_isScalar:false
_value:Array(3)
0:"[email protected]"
1:"Bob Smith"
2:{adminUser: false, basicUser: true} length:3
__proto__:Array(0)
__proto__:Subject
My Behavior Subject has the following being sent to it. Why am i getting null at the start.
user: BehaviorSubject<User> = new BehaviorSubject<User>(null);
// The behavior-roles of the user.
this.afAuth.authState
.switchMap(auth => {
if (auth) {
/// signed in
const authData = this.db.list<User>('users/' + auth.uid).valueChanges();
console.log(authData);
return this.db.list<User>('users/' + auth.uid).valueChanges();
} else {
/// not signed in
return Observable.of(null);
}
})
// .subscribe(console.log); // check the subscription
.subscribe((userData) => {
console.log(userData);
this.user.next(userData);
// this.user.next(user);
// console.log(this.user.next(userData));
});
}
The results i am having issues with:
Check Value false authguard.service.ts:39
Route was False authguard.service.ts:26
Check Value true
I run console.log and the value shows up null first therefore has a false response. Then it runs again and becomes true. This all happens after running the page initially. I need for my check value to be true on load.
Share Improve this question edited May 10, 2018 at 18:00 Kevin Summersill asked May 10, 2018 at 16:53 Kevin SummersillKevin Summersill 7582 gold badges9 silver badges22 bronze badges 1- .value() should do it – Kevin192291 Commented May 10, 2018 at 17:00
3 Answers
Reset to default 15You should just be able to call the name of the BehaviorSubject with the .getValue() so something like:
let x = new BehaviorSubject<any>;
...
x.getValue()
I got the same problem. I always get my initial value (which is null) and never the emitted values. skip()
-method dosen't help me but the skipWhile()
-method was the trick.
behaviorSubject.pipe(
skipWhile(value => !value), // skip null values
take(1)) // in my case, I need the value only once
.subscribe(value => doYourWork());
Edit
If it possible, then it´s the best solution to switch to a ReplaySubject
of size 1. You need no .skip()
or .skipeWhile()
anymore.
Here is an example.
// replaySubjects have no initial value
let subject = new ReplaySubject<YourType>(1);
subject.pipe(take(1)).
// no null-values anymore!
.subscribe(value => doYourStuff());
// subscribers dont get any value until a next()-call
subject.next(youValue);
// and you can hide some methods, when you declare it as observable or subject
// hide replaySubject specific informations
let publicSubject: Subject<YourType> = subject;
// hide subject informations (like .next())
let publicSubject2: Observable<YourType> = subject;
I have officially answered my question. May not be the right way but it sure did work.
The BehaviorSubject from rxjs produces both the initial and current value at that particular steam of time. Now if you want to bypass the initial value (which in my case was null) then before you subscribe to it, make sure to use the skip operator.
Which I used in this case to skip the first value skip(1).
// RxJS v6+
import { interval } from 'rxjs';
import { skip } from 'rxjs/operators';
//emit every 1s
const source = interval(1000);
//skip the first 5 emitted values
const example = source.pipe(skip(5));
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));