Get Last Value from Observable in Angular 8
Solution 1
You are getting a little mixed up with your behaviour subject here and what it does for you.
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 your subscribe method.
If you have initial state, you can use a behavior subject to initialize the subject and ensure new subscribers always receive a value.
If you don't have initial state, but want to ensure new subscribers get the last emitted value on subscribing (if one exists), then you can use replay subject.
All of the values that go into a subject are of type T, where you have Subject<T>
. So in your case, everything going into the subject should be an AddressDto
.
If you have an initial address, then you would set up you behavior subject like this:
// somehow get my initial address
const address = new AddressDto(); //
const test = new BehaviorSubject<AddressDto>(address);
// all subscribers will receive this address upon subscribing
// ... some things happen
// now I have another address, emit that
const newAddress = new AddressDto();
test.next(newAddress);
// all new subscribers will now receive newAddress upon subscribing
On the other hand, if you don't have an initial address, you can use a replay subject like this:
// always emit the last address to new subscribers by intitialing with a 1
// New subscribers won't receive an address until one is emitted
const test = new ReplaySubject<AddressDto>(1);
// ... some things happen
// now I have my first address, emit that
const firstAddress = new AddressDto();
test.next(firstAddress);
// all current subscribers receive firstAddress
// all future subscribers will receive firstAddress upon subscribing
// ... some things happen
const secondAddress = new AddressDto();
test.next(secondAddress);
// all current subscribers receive secondAddress
// all future subscribers will now receive secondAddress upon subscribing
Edit:
You have asked about storing the last value in a variable. What you mean by this is ambiguous, so 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 / observable, you start getting into the idea of the observable pipe. All sorts of stuff can happen inside a pipe - just think of it as a series of steps of things that can happen to an object, much like a series of chained array functions on a normal javascript array.
One of the things you can do in a pipe is to perform "side-effects" in a tap()
operator. This just means that you can do stuff in the middle of a pipe while letting the data pass through. One of these things could be store the value in a variable (or local storage or whatever) for some purpose.
If you have control of what's going into the subject, it seems redundant to do this in a pipe, so I'll use the example of caching the result of an http request.
this.http.get(url).pipe(
// transform the http response into an object you have created
map(response => this.mapResponseToMyClass(response)),
// store the mapped object in a local property for later use
tap(myClass => {
// you can perform any side-effect actions you want here
console.log(myClass);
// store the value in a variable
this.cachedMyClass = myClass;
})
);
Piping your own subject is no different - everything that comes into a subject will go through a pipe and then out to the subscriber(s).
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 still comes out here to all subscribers
).asObservable();
}
Solution 2
Observable does not store value. You should have subscribed to Observable before you have push data in Observable stream to receive value. I think Your AddressObservable is an Observable, not BehaviorSubject. If you convert AddressObservable to BehaviorSubject. It will work. In case AsyncPipe it is working because it async pipe subscribe for the same.
Change AddressObservable to type: BehaviorSubject
Related videos on Youtube
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
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>
-
Kurt Hamilton about 4 yearsYour code looks a little confusing. You are initializing a behavior subject with a string, and then emitting another observable through the subject. Can you post the relevant code to give this post context
-
-
Admin about 4 yearsok, How do I store the value of the last dto in a variable after doing next? or display in console log? trying to setup subscription properly, thanks
-
Admin about 4 yearsalso don't see the subjects linking to AddressObservable above
-
Admin about 4 yearsneed linkage to observable and subscription example would be helpful
-
Kurt Hamilton about 4 yearsNot sure exactly what you mean, so I've added an example of how you can log to the console and store to a local variable. There are many better tutorials on using observables and pipes than this, but I appreciate it can all be a bit overwhelming to start with
-
Peter Nixey almost 4 yearsThis is such a helpful answer - ty