1

When I use pipe and takeLast, then the whole process stops.

Here is my original code:

this.request$.subscribe(req => {
  this._service.run(req!).subscribe(res => {
    this._service.fetch().subscribe(resources => {
      console.log('hi'); // This 'hi' logs two times, but I want to get only the last 'hi'.
    });
  });
});

Here is my try:

this.request$.subscribe(req => {
  this._service.run(req!).subscribe(res => {
    this._service
      .fetch()
      .pipe(takeLast(1))
      .subscribe({
        next: x => console.log('got value ' + x),
        error: err => console.error('something wrong occurred: ' + err),
        complete: () => console.log('hi')
      });
  });
});

However, nothing happends in my try and nothing is logged anymore.

Updated my question

I have updated my second example as below, but not working yet:

this.request$.pipe(
  mergeMap((req) => this._service.run(req!)),
  mergeMap((res) => this._service.fetch().pipe(takeLast(1)))
).subscribe((resources) => {
  console.log('hi'); // This line is not executed, but I expect to be executed one time.
});
Mohsen
  • 772
  • 1
  • 7
  • 15
  • 2
    You shouldn't subscribe inside another subscribe – Liam May 26 '21 at 13:07
  • 1
    Beyond that we'll need much more info than "stops working" – Liam May 26 '21 at 13:07
  • by `stops working`, I mean `hi` is not logged in the console anymore when I use my second example. And I also didn't understand your first comment. What should I do then? – Mohsen May 26 '21 at 13:10
  • Yes I appreciate that, what is your input stream and what do you expect? Please create a [mcve] – Liam May 26 '21 at 13:11
  • If you don't understand my first comment then I'd suggest you may need to read more on [RXJS](https://www.learnrxjs.io/) and functional programming in general – Liam May 26 '21 at 13:13
  • 1
    [Or this may help](https://stackoverflow.com/a/52317734/542251) – Liam May 26 '21 at 13:14
  • Okay, I will read them to understand what the problem is. – Mohsen May 26 '21 at 13:15
  • Does this answer your question? [How to get last emitted value of on Observable in the subscription when next is called after the subscription?](https://stackoverflow.com/questions/67445003/how-to-get-last-emitted-value-of-on-observable-in-the-subscription-when-next-is) – dota2pro May 26 '21 at 13:20
  • @dota2pro, let me check and tell you then. – Mohsen May 26 '21 at 13:35
  • I updated my question, but not solved yet. – Mohsen May 26 '21 at 13:42
  • Like I said, *what is your input stream and what do you expect?* You still haven't given us a [mcve] to work with. There isn't enough information in this question to answer – Liam May 26 '21 at 13:44
  • this._service.fetch() returns an `Observable – Mohsen May 26 '21 at 13:59

1 Answers1

2

As mentioned in the post I commented you need to complete() observable so that Rxjs knows which is the last one, See Stackblitz

import { Component, Input, OnInit } from '@angular/core';
import { from, Observable, Subject } from 'rxjs';
import { last, takeLast, takeUntil } from 'rxjs/operators';

@Component({
  selector: 'hello',
  template: `
    <h1>Hello {{ name }}!</h1>
  `
})
export class HelloComponent implements OnInit {
  @Input() name: string;
  request$ = new Observable<any>();
  end$ = new Subject();
  ngOnInit() {
    this.request$ = from([1, 2, 3, 4, 5]); // create Observable
    this.request$
      .pipe(
        // mergeMap((req) => this._service.runRequest(req!)),
        // mergeMap((res) => this._service.fetchResources().pipe
        takeLast(1),
        takeUntil(this.end$)
      )
      .subscribe(resources => {
        console.log('hi'); // This line is not executed, but I expect to be executed one time.
      });

    this.end$.complete(); // Finish Subject to end subscription
  }
}
dota2pro
  • 7,220
  • 7
  • 44
  • 79