RxJS operators: retry vs repeat?
Tags: rxjs, javascript, beginners, webdev
Published: 2019-04-26 15:21:29

---
title: RxJS operators: retry vs repeat?
published: true
description: So what is the difference between *retry* and *repeat* in RxJS? Neat use-cases for both of these operators to help you learn them better.
tags: rxjs, javascript, beginners, webdev
---
![Pic by Luca Florio](https://i.ibb.co/8P5P7t6/27926246623-9fb412d3a9-z.jpg)
> So what is the difference between retry and repeat in RxJS? Learn neat use-cases for both of these operators to help you understand them better.

## Intro
When I just started learning RxJS a few years ago it was not so obvious for me why we have two operators in RxJS for doing repeat logic. Not only I may have such a question, so in this article, I will review both **retry** and **repeat** operators as well as possible use-cases for them.

## retry...or repeat?

In RxJS both **repeat** and **retry** operators allow you to conditionally re-subscribe terminated source observable they were applied to.
Both of them make source observable sequence will be restarted.

The main distinction is 

**repeat** - resubscribes when it receives onComplete(), but not by error.
**retry** - resubscribes when it receives onError().

In terms of possible use-cases:
> If you want to repeat SUCCESSFUL data fetching wrapped in observable - use **repeat**.
> If you want to repeat FAILED data fetching wrapped in observable - use **retry**.

Now let's take a closer look at each of them with examples.

## retry
 
> **retry(count)**

  It returns the Observable that mirrors the source Observable with the exception of an error.
  If the source Observable calls error, this method will resubscribe to be source Observable for a maximum of *count* re-subscriptions
     
  **count** - Number of retry events before failing. Default is -1.

Here is vanilla JS example for dealing with an unstable network connection. we make observable-wrapped Ajax call and use retry operator. in case first Ajax call returns error retry operator will re-do an ajax request three more times.
if one of these attempts is successful it will provide data for onNext subscribers callback.
if all three additional attempts fail then an error will be propagated to subscribers onError callback handler.

{% gist https://gist.github.com/kievsash/eba2de3b406afb8c9e300c008eda1fbe %}

Lets try to run it in a [codepen](https://codepen.io/kievsash/pen/zXevvo?editors=0010).

And as you can see - we have one failed requests and 4 more retry attemps (they all failed as well since for learning purposes we were trying to reach non-existing url).

![retry](https://i.ibb.co/zrvBV2b/retry-output.png)

### To conclude:
1. **retry** returns Observable that mirrors the source Observable.
2. If source Observable calls error, this method will resubscribe to the source Observable (repeat running source sequence) for a maximum of count param value re-subscriptions.
3. If one of the retries runs succeeded - event data will be provided to onNext callback handlers of subscribers. If all retry runs fail - an error will be propagated to onError handlers.
4. One of the possible use-cases - ajax failed requests retry.


## repeat
> **repeat(count)**

Returns an Observable that repeats the stream of items emitted by the source Observable at most *count* times.
     
  **count** - The number of times the source Observable items are repeated, a count of 0 will yield an empty Observable. Default is -1.

Look at this example:
![repeat](https://i.ibb.co/bFcv0CC/repeat.png)

We take source sequence and run it twice.
Notice that *repeat* operator treats the initial run as the first one.

Now let's take a look at more complicated use-case - say, we have a back-end, but it brings not all data at once but by pages. So let's implement a fetching of a specific number of paginated data portions from a back-end:

{% gist https://gist.github.com/kievsash/4dc91fa626290fd09b9b798fbbd5b5f8 %}

Before I describe this code - pay attention that we wrapped source observable in **defer** functions from RxJS. Each time when *repeat* operator re-run source observable - *defer* will fun its factory function - so our url will have updated counter value. You can read more about *defer* [here](https://rxjs-dev.firebaseapp.com/api/index/function/defer)

Lets now observe how it works:
1. When we subscribe source makes first call with page = 0 (counter variable).
2. After data successfully fetched, we emit data to subscribers. And then source observable completes - so *repeat* starts working - and re-run source - it is *defer* function in our case. 
3. Defer function calls its factory function and returns ajax observable with new counter value. So now we requesting API with page = 1.
4. New page of data is emitted to subscribers as well.

You can try to run this code yourself in a [codepen](https://codepen.io/kievsash/pen/EJrKoj?editors=0010).



### To conclude:
1. **repeat** returns an Observable that repeats the stream of items emitted by the source Observable at most *count* times.
2. **count** param - the number of times the source Observable items are repeated, a count of 0 will yield an empty Observable. Unlike retry - repeat operator treats initial source$ run as the first try, so the source will be repeated (count - 1) times.
3. **repeat** - resubscribes when it receives onComplete() from source sequence, but not by error.
4. If you need source observable to repeat with different params - use Rx.JS defer function.


## Can we use them together?

Can we use these both **retry** and **repeat**?
Definitely yes! If you want to repeat source requests and retry if one of the repeated calls failed - you can use both operators.

Here in this example, we request paginated information twice with **repeat** operator. If some of the requests fail - retry will re-run it.

{% gist https://gist.github.com/kievsash/614f8c7fbcbe644b525000d1fe8e2a45 %}


## retryWhen and repeatWhen

When I first saw **retry** and **repeat** operators examples my thought was - can I add some delay between retried ajax calls? 
And this is when operators *retryWhen* and *repeatWhen* come into play - but this is the topic of another article - [let's keep in touch](https://twitter.com/El_Extremal)!

## Video course for RxJS beginners with detailed explanations.

> Packtpub.com and I prepared a whole [RxJS course](https://www.packtpub.com/web-development/hands-rxjs-web-development-video) with many other details of how you can solve your every-day developer’s tasks with this amazing library. It can be interesting for beginners but also contains advanced topics. Take a look!