1

I'm using Angular with server-side rendering and TransferState to transfer http data from server to browser. Here is my code:

getProducts() {
    let products = this.tstate.get(PRODUCT_KEY, null as any);
    if (products) {
        return of(products);
    }

    return this.http.post<any>(config.baseUrl+ 'product', {}).pipe(map(
        data => {
            this.tstate.set(PRODUCT_KEY, data as any);
            return data;
        }
    ))
}

In the first load, I get the data from http request. Then the state is initializing. After that, when the route changes, still transfer state keeps the data, so I can't send the request to get the data. Any idea how to reset transfer state in route changing?

Vahid Najafi
  • 4,654
  • 11
  • 43
  • 88
  • Why don't you unset the data right after retriving it from the cache? – David Jun 04 '19 at 12:09
  • @David This even doesn't solve the problem. At first time, imagine I unset the from the cache and it send a new request, then I go to another menu, and come back to the previous menu, still, it will use the cache. – Vahid Najafi Jun 04 '19 at 12:23
  • Sorry, I'm not sure I understand. If you want to use the transfer state only once, then unset the key after retrieving the data and do not cache the next requests. The other option is to listen to router events and clear the cache when you want – David Jun 04 '19 at 12:27
  • What do you mean by `do not cache the next requests`? (Sorry I explained in a bad way, let me explain again) – Vahid Najafi Jun 04 '19 at 12:29
  • I mean do not use `this.tstate.set(PRODUCT_KEY, data as any);` if you are client side – David Jun 04 '19 at 12:30
  • Imagine I have menu1, menu2, and menu3. I have http request in menu2. First I open menu1. Then I go to menu2. It sends http request and saves the cache. I go to menu3, then go to menu 2, and it uses the cache (after that I can unset the cache). – Vahid Najafi Jun 04 '19 at 12:31
  • Ok, let me test your workaround. – Vahid Najafi Jun 04 '19 at 12:31
  • @David Thank you, it seems it works fine. If you add your comment as an answer, I would accept it as an accepted answer. – Vahid Najafi Jun 04 '19 at 12:51

1 Answers1

2

You could listen to router events and unset cached data after navigation

constructor(private router: Router,
//...)
{
  this.router.events.subscribe(evt => {
  if (evt instanceof NavigationEnd)
  {
    this.tstate.remove(PRODUCT_KEY);
  }

}

Or you could stop setting transfer data if you are client side

constructor(@Inject(PLATFORM_ID) private platformId: Object
//...)
{
}

getProducts() {
    let products = this.tstate.get(PRODUCT_KEY, null as any);
    if (products) {
        this.tstate.remove(PRODUCT_KEY);
        return of(products);
    }

    return this.http.post<any>(config.baseUrl+ 'product', {}).pipe(map(
        data => {
            if(!isPlatformBrowser(this.platformId)
            {
                this.tstate.set(PRODUCT_KEY, data as any);
            }

            return data;
        }
    ))
}
David
  • 33,444
  • 11
  • 80
  • 118