Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redo requests after a certain time / cache expiration #6260

Closed
StefanKern opened this issue Apr 25, 2021 · 6 comments
Closed

Redo requests after a certain time / cache expiration #6260

StefanKern opened this issue Apr 25, 2021 · 6 comments

Comments

@StefanKern
Copy link

StefanKern commented Apr 25, 2021

Missing feature in rxjs 7

In rxjs v7 publishReplay, refCount, etc where deprecated and share and shareReplay are now the 'only' options when wanting use the result of an observable in multiple parts of the code, without redoing the complete 'observable'. An example for this is an API call, where the result is used in two places of the application, but you don't want to hit the network each time.

This was usually done with publishReplay and refCount. If you wanted to limit the time these requests where valid, you could set a windowTime in publishReplay and after "X"ms, the request repeated. (you also had to add a take(1) at the end, but that would be another question/issue). This solution was taken from SO: https://stackoverflow.com/a/54957061

With share or shareReplay, you cannot reproduce the same behaviour.

You can pass a windowTime to shareReplay, however after the time is exceeded, no more values are emitted at all!

Example how it was working before:

export class AppComponent {
  name = "Angular " + VERSION.major;

  urlofApi = "https://api.github.com/search/repositories?q=helloWorld";

  testX = this.http.get(this.urlofApi).pipe(
    tap(() =>
      console.log(
        `++ api was newly called at ${new Date().toLocaleTimeString()} ++`
      )
    ),
    publishReplay(1, 5000),
    refCount(),
    take(1)
  );

  constructor(private http: HttpClient) {}

  test() {
    console.log("Requesting data from API");
    this.testX.pipe(take(1)).subscribe(() => console.log("completed"));
  }
}

rxjs: 6.6.3
Stackblitz: https://stackblitz.com/edit/angular-ivy-tyrbdw?file=src%2Fapp%2Fapp.component.ts
Result:
image

Example with shareReplay

testX = this.http.get(this.urlofApi).pipe(
  tap(() =>
    console.log(
      `++ api was newly called at ${new Date().toLocaleTimeString()} ++`
    )
  ),
  shareReplay(1, 5000)
);

rxjs": "^7.0.0-rc.2
Stackblitz: https://stackblitz.com/edit/angular-ivy-ggkvpw?file=src%2Fapp%2Fapp.component.ts
Result;
image

Note how the Observable doesn't emit anything anymore, after 5sec.

Expected behaviour:

Requests are repeated once the windowTime is exceeded.

@StefanKern
Copy link
Author

@cartant I cannot follow your comment. Tried setting refCount to true, and then it does the request each time.

Was it intended more as an internal comment?

PS: seems like I exceeded the limit for calling the github api with HelloWorld. Had to change the searchstring...

@cartant
Copy link
Collaborator

cartant commented Apr 26, 2021

I left the terse comment because it appeared to be a straightforward refCount issue - that's what's mentioned in the linked SO answer.

Looking at it more closely, I suspect that the behaviour upon which you are relying is a bug - see #5696 - as it makes no sense. Once a subject errors or completes, that's supposed to be it; the subject should not forward additional notifications it might receive from any source to which it is subscribed. And publish - and its variants - create a single subject when the operator itself is called; the subject is not reset when the source errors or completes.

Working as intended, AFAICT. A bug fix is pretty much always someone else's breaking change, I guess.

@StefanKern
Copy link
Author

I see, hmm but I'm kinda relaying on this functionallity. Is there a way to get the same behaviour with other functions?

To me, the usecase seems quite reasonable :)

@cartant
Copy link
Collaborator

cartant commented Apr 26, 2021

I don't have time, ATM. Ask on SO - or in discussions in this repo or both - and reference the original SO answer and my comment above. It's definitely relying on a bug, IMO, so I'm closing this.

@martinsik
Copy link
Contributor

martinsik commented Jul 14, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants