How do I get the last value from an Observable in Angular 8?
let test = new BehaviorSubject<any>('');
test.next(this.AddressObservable);
let lastValue = test.subscribe(data=>console.log(data.value));
For some reason it is not working, checking debugger.
However, this is working in html, AddressObservable | async
Trying to utilize this link, want to store value in variable or display in console log. Any newer syntax would be helpful .
How to get last value when subscribing to an Observable?
Note:
AddressObservable
is of type: Observable<AddressDto>
Judging by the question, there seems to be confusion with the BehaviorSubject
and what it does.
A Subject
is effectively a stream of values from some source that you can subscribe to. Whenever a new value is emitted, it arrives in the subscribe
method.
If you have an initial state, you can use a BehaviorSubject
to initialise the subject and ensure new subscribers always receive a value.
If you don't have an initial state, but want to ensure new subscribers get the last emitted value on subscribing—if one exists—then you can use ReplaySubject
.
All of the values that go into a Subject
are of type T, where you have Subject<T>
. Therefore, in your case, everything going into the Subject
should be an AddressDto
.
If you have an initial address, then you would set up your BehaviorSubject
as follows.
// Somehow get the initial address.
const address = new AddressDto();
const test = new BehaviorSubject<AddressDto>(address);
// All subscribers will receive this address on subscribing.
// Something happens.
// There is another address; emit that.
const newAddress = new AddressDto();
test.next(newAddress);
// All new subscribers will receive newAddress on subscribing.
On the other hand, if you don't have an initial address you can use a ReplaySubject
as demonstrated below.
// Always emit the last address to new subscribers by intitialising it with the number 1.
// New subscribers won't receive an address until one is emitted.
const test = new ReplaySubject<AddressDto>(1);
// Something happens.
// Get the first address, and emit it.
const firstAddress = new AddressDto();
test.next(firstAddress);
// All current subscribers receive firstAddress.
// All future subscribers will receive firstAddress on subscribing
// Something happens.
const secondAddress = new AddressDto();
test.next(secondAddress);
// All current subscribers receive secondAddress.
// All future subscribers will receive secondAddress on subscribing.
You asked about storing the last value in a variable, which is ambiguous. I'm going to assume you mean at the source as that's more complex.
Once you get your head around the concept of Subject
and Observable
, you might understand the idea of the Observable
Pipe
. All sorts of stuff can happen inside a Pipe
; think of it as a series of steps of things that can happen to an object. It is similar to a series of chained array functions on a normal array in JavaScript.
One of the things you can do in a Pipe
is to perform "side effects" in a Tap
operator. This means that you can do stuff in the middle of a Pipe
while letting the data pass through it. To give two examples, you could store the value in a variable, or in localStorage
.
If you have control of what's going in the Subject
, it seems redundant to do this in a Pipe
; therefore, the following example shows how to cache the result of an HTTP request.
this.http.get(url).pipe(
// Transform the HTTP response into an object that is created.
map(response => this.mapResponseToMyClass(response)),
// Store the mapped object in a local property for later use.
tap(myClass => {
// Perform any 'side effect' actions you want, such as the below.
console.log(myClass);
// Store the value in a variable.
this.cachedMyClass = myClass;
})
);
'Piping' your own Subject
is no different. Everything that goes into a Subject
will go through a Pipe
and is then outputted to the subscriber.
private subject = new Subject<AddressDto>();
getPostcode(): Observable<string> {
// Reuse the local Subject. All subscribers to this function will receive addresses that have come through the Pipe.
return subject.pipe(
map(address => address.postcode),
// Store the last postcode in a local property.
tap(postcode => this.lastPostcode = postcode)
// The postcode is outputted here to all subscribers
).asObservable();
}