Get Last Value from Observable in Angular 8

13,919

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

Share:
13,919

Related videos on Youtube

Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    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
      Kurt Hamilton about 4 years
      Your 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
    Admin about 4 years
    ok, 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
    Admin about 4 years
    also don't see the subjects linking to AddressObservable above
  • Admin
    Admin about 4 years
    need linkage to observable and subscription example would be helpful
  • Kurt Hamilton
    Kurt Hamilton about 4 years
    Not 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
    Peter Nixey almost 4 years
    This is such a helpful answer - ty