RxJs: take(1) vs first()
Tags: rxjs, angular, chatgpt, webdev
Published: 2023-01-12 09:48:50

## Overview

When using Angular, it is inevitable that you will also commonly be using RxJs. Together these tools can do many amazing things. There is a seemingly infinite amount of different operators that I am constantly learning about. One that I have recently come across is `first()`. I always have used `take(1)` in order to access the first item emitted from an observable stream and then complete the observable. Finding out about `first()` initially seemed like a cool way to clarify my code a little more. But, after more research, I found out that there is enough of a difference that they may not necessarily be used interchangeably. 

*Bonus: chatGPT gave me an incorrect answer about the difference between the two operators. More on that later as well.*

## Setup - Create A Sandbox Project

Go to [Stackblitz](https://stackblitz.com) and start a new "RxJs" project. Or you can fork my [Stackblitz here](https://stackblitz.com/edit/take-vs-first?file=index.ts) to allow you to follow along with my example.


## Similarities Between take(1) & first()

take(1) is a great way to pick the first, and only the first, value from an observable stream. It is extremely simple to use as you can see here: 

```js
const source$: Observable<any> = from([1, 2, 3]);

source$
  .pipe(
    take(1),
    catchError((error) => {
      console.log({ error });
      return of();
    }),
    tap((value) => console.log({ value }))
  )
  .subscribe();
```

The `console.log` will be `value: 1`, since that is the first item in the array. 
*(As a side note, if you don't know why it emits `1` instead of the whole array passed into the `from()`, check out my post about that operator [here] (https://dev.to/blamb31/of-vs-for-how-to-use-each-and-what-is-the-difference-1h9n).)*

Similarly, `first()` can perform the exact same functionality. In my opinion, it also accomplishes the task with more readability than take(1). An example of using `first()` would look like this: 

```js
const source$: Observable<any> = from([1, 2, 3]);

source$
  .pipe(
    first(),
    catchError((error) => {
      console.log({ error });
      return of();
    }),
    tap((value) => console.log({ value }))
  )
  .subscribe();
```

You'll see in these two examples that they each perform the same task and log the same value, `value: 1`. Both operators also complete the observable after they have been called, so there is no need to unsubscribe from the observable. 

Now we can look at where these operators behave differently and why you might choose one over the other. 

## Differences Between take(1) & first()

Lets change the `source$` variable to now equal `from([])`. You'll now be able to find the difference between these operators. 

If this were to happen while using `take(1)`, you would never know as nothing would be logged, and no error would be caught. 

On the contrary, if using `first()` and there is no value emitted from the observable, there will still be no value logged, but you would see a value for the `error` within the `catchError` block. 

That is it! That is the difference between the two operators. Kind of anti-climactic right? Well lets find an example of why this difference could be important so you can know which operator to use in the future. 

## How Do I Choose One?

There will be many situations where you will never notice a difference between the two operators. But if you need to know for sure that there is a value being emitted, then the first() operator could come in handy. 

For example, you might be building a login component where you're handling login credentials and, when the user clicks "Submit", pushing them to an observable. If the user clicks "Submit" and the username or password field does not contain values, then you could use the `first()` operator to throw an error and stop the login attempt. 

Or you might be logging the user out of an application and it is not necessary to look for a specific value or any value at all. You know that the action will happen once and then the observable can complete. This would be a great situation for `take(1)`. 

## Conclusion

There are so many solutions to the same problem, but not all solutions are created equally. So having more tools to use, allows you to be able to find the best solution to a given problem. `take(1)` and `first()` both have their place in the world of RxJs. Hopefully, now you are able to better find those places and use them appropriately. 

## Bonus: ChatGPT

I have been trying to use ChatGPT as a resource in my coding as well as my learning. It has been a great help to me in both aspects. I have found however that it is often wrong when explaining definitions to me. For this post, I asked it what the difference was between the two operators. Here is the answer that I got:

![ChatGPT response to my question](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8xe5jpwuu8e0havdyp4.png)

Obviously, this is incorrect, and the real answer was the inverse of what it told me. All of this to say, even though ChatGPT is an awesome tool it is capable of being incorrect. So make sure to fact check with other sources before just taking its word as law.