<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stas Kohut</title>
    <description>The latest articles on DEV Community by Stas Kohut (@diamonddarrell).</description>
    <link>https://dev.to/diamonddarrell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F338810%2F7b98b991-0c9e-4ea1-9aec-196148ab45db.jpeg</url>
      <title>DEV Community: Stas Kohut</title>
      <link>https://dev.to/diamonddarrell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diamonddarrell"/>
    <language>en</language>
    <item>
      <title>NX for React</title>
      <dc:creator>Stas Kohut</dc:creator>
      <pubDate>Wed, 03 Aug 2022 04:34:00 +0000</pubDate>
      <link>https://dev.to/diamonddarrell/nx-for-react-450k</link>
      <guid>https://dev.to/diamonddarrell/nx-for-react-450k</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Hello everyone, my name is &lt;a href="https://github.com/diamond-darrell"&gt;Stas Kohut&lt;/a&gt;. I'm a frontend developer and have been doing frontend for 8 years. During those years, I participated in numerous projects using different frontend technologies. But recently, I have stuck to the React ecosystem, so I'll speak from React developer's perspective in today's post. However, it can be applied to any frontend technology so stick around.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A little disclaimer: I'll try to tell a story rather than read it as a manual. It's not a tutorial! Given that there won't be any code examples. My goal is to raise awareness of the technologies and maybe spark someone's interest to do some research for themselves on the topic. And maybe after that, you would want to use it in your next project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's NX?
&lt;/h2&gt;

&lt;p&gt;In short, it's a developer experience (DX for short) toolkit that helps building projects inside monorepo architecture. Think of it as create-react-app (or angular-cli) for monorepos.&lt;/p&gt;

&lt;p&gt;So it might be obvious from the name: monorepo stands for the mono repository - a repository that contains all domain-related files. And I mean ALL files: your backend, your frontend, your utility libraries, documentation, etc. In opposition to that, polyrepo is the approach where each of your domain-related projects has its own repository. I couldn't find when the first monorepo was created. Still, Wikipedia says this approach dates from the early 2000s and is currently widely used by Google, Facebook, Microsoft, and other large and small companies.&lt;/p&gt;

&lt;p&gt;Knowing what monorepo is, we can say that NX is a tool to manage monorepos. It was created by ex-google employees who worked on Angular.js and Angular in particular: &lt;a href="https://github.com/jeffbcross"&gt;Jeff Cross&lt;/a&gt; and &lt;a href="https://github.com/vsavkin"&gt;Viktor Savkin&lt;/a&gt;. In 2016 they left to start their own consulting firm Narwal Technologies Inc (Nrwl for short), and 2 years after, they released the first alpha version of their own monorepo manager.&lt;/p&gt;

&lt;p&gt;Being angular guys to the bone, the first versions supported only angular projects. Heck, they even used literal angular.json for their config. A bit later, NX became a framework agnostic. At first, the meat of this tool was a great set of generators for various frameworks that made starting an app a single command job (create-react-app wink-wink). And they didn't stop on it and added a bunch of stuff: a visual inspector of the dependency graph, github actions, cloud caching, and so on.&lt;/p&gt;

&lt;p&gt;That's all cool, but you might ask yourself why you need it. And most importantly, why choose NX over other options: Lerna, Turborepo, Bazel, or even npm/yarn workspaces (and the list goes on)?&lt;/p&gt;

&lt;p&gt;Okay, the answer to the first question depends on your situation and preferences. As I mentioned, I'm here to share, not sell. So, you'll need to do the homework yourself. I found a great &lt;a href="https://github.com/joelparkerhenderson/monorepo-vs-polyrepo"&gt;page&lt;/a&gt; about the pros and cons of both approaches. If you decide to try monorepo, be my guest and suit yourself with whatever option is available. I can share an excellent website that might help you decide &lt;a href="https://monorepo.tools/"&gt;https://monorepo.tools/&lt;/a&gt;. My story of using NX is based on occasion and curiosity, but I'll tell it later.&lt;/p&gt;

&lt;p&gt;Next, I want to talk about some use cases. And although I'll be talking about NX, most of the stuff applies to other monorepo tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can you use NX?
&lt;/h2&gt;

&lt;p&gt;The prime example of the setup is to have both the API and the client project in the same repo. You can run everything with a single command, share typings, and develop full-stack features without switching between editor windows. You might think it's most suitable for full-stack developers. In some way, it is. But as a dedicated frontend or backend developer. Sometimes you want to peek at what the heck is going on over there: how the endpoint builds the response or how the frontend handles your API. But often, you even don't have access to other team repo. I know. I've been there.&lt;/p&gt;

&lt;p&gt;NX nicely fits the microservices architecture: small isolated applications that might have some shared interfaces of utilities.&lt;/p&gt;

&lt;p&gt;Of course, you can argue that it might not always work. Not all benefits can be used. And it's true, NX works great with &lt;a href="https://github.com/nrwl/nx/issues/2767"&gt;JavaScript frameworks only&lt;/a&gt;. If your backend is not Node.js based, you won't be able to use it. I invite you to learn about other language-agnostic tools &lt;a href="https://github.com/korfuri/awesome-monorepo"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another example is to use it for libraries. For instance, UI-kit. I often see that a theme, icons, basic components, and advanced components are separated in such libraries for consumer convenience. It's reasonable to release them separately. The end user might not need all of the packages. And NX shines here, allowing you to develop everything together but release it separately.&lt;/p&gt;

&lt;p&gt;Also, you can use it for a single frontend (or backend) project. At first, it may not have any sense. Why would you need a monorepo for a single project? But NX has a trick up its sleeves - the libraries structure. You see, NX provides a way to have shared libraries area between several applications. Nothing unusual. However, they introduce libraries types approach where you should put your libs under &lt;a href="https://nx.dev/structure/library-types#library-types"&gt;4 basic categories&lt;/a&gt;: feature, data, UI, and utils. It helps structure application by layers. All API interactions code and state management should go to data libraries. UI components - to UI libraries and so on. Since it's just a convention, you can just ignore it altogether and use it as a basic area for shared code. Or you can create your own types of libraries to fit your needs in the project. For instance, we wanted to share typings separately at some point and made a types-library type of signaling that typings should go there.&lt;/p&gt;

&lt;p&gt;Library categories have a dependency constraint, meaning a specific library type can depend only on a particular type of other libraries. For example, UI components usually shouldn't interact with the API directly. This is a job of a container. So following that, UI libraries shouldn't import any data libraries. Or utils shouldn't depend on anything other than maybe other utils. And it's reflected in libraries hierarchy. By default, it's not enforced and is just a convention, but NX provides a tool to prevent unwanted imports.&lt;/p&gt;

&lt;p&gt;Those are just examples that I’m more familiar with. NX supports various &lt;a href="https://nx.dev/packages"&gt;JavaScript frameworks and tools&lt;/a&gt;, so it’s a good chance it already supports what you want to achieve.&lt;/p&gt;

&lt;h2&gt;
  
  
  My path with monorepos and NX
&lt;/h2&gt;

&lt;p&gt;My first encounter with monorepo was way back in 2017. I ended up on a project that has its own UI library, and this library was a Lerna-based monorepo. I didn't participate in choosing the monorepo approach or the tool. It was already there. But I liked the approach because all components depended on a theme, and it was straightforward to navigate a single project during its development. Also, releasing all libraries as separate libraries from a single repo seemed like magic to me at the time. Eventually, as angular libraries matured, we replaced Lerna with the native angular solution, which looked like a better option from the support view.&lt;/p&gt;

&lt;p&gt;The next time I worked with monorepo was a few years later. In 2020 we were starting a new project, and the setup was very similar to the first project: an app and a UI library. We started developing the UI library first. And because we already used Lerna, the choice was a no-brainer. However, once we were about to start developing the app, NX began to gain popularity. They introduced React support, and out of curiosity, we began investigating it. The libraries hierarchy appealed to us, and we decided to give NX a shot with the app. Although we never had a chance to convert the UI components library to NX.&lt;/p&gt;

&lt;p&gt;At the end, it was a good choice. The project structure looked clear and easy to follow (once you wrap your head around NX concepts). Dependency constraints prevented us from doing silly stuff (most of the time). So, needless to say, we started to use NX in all oncoming projects.&lt;/p&gt;

&lt;p&gt;I never used NX with the backend project in the production, but I had some toy projects exploring that idea, and I liked it.&lt;/p&gt;

&lt;p&gt;Another "success story" using NX was on a project where we developed a chat widget. It was not a standalone app and intended to be integrated into different environments we didn't own. We came up with an idea to create a hoster app that will simulate all possible environments to test our widget without a dependency on another team. NX was an excellent fit for such requirements because we didn't have to pollute our main app (the widget) with the throwaway test code. It lived as a separate app inside the monorepo.&lt;/p&gt;

&lt;p&gt;By the way, we liked the idea of the hoster app, and for the next project we did, we created a similar app to provide a dynamic environment config for the main app. But it's a story for another time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Struggles
&lt;/h2&gt;

&lt;p&gt;You might think that since I shared only success stories, it means that all went nice and smooth. Unfortunately, it's not always great, and monorepos and NX, in particular, have their own set of problems.&lt;/p&gt;

&lt;p&gt;I want to start with the documentation. The NX team provides a ton of learning material: they have a video course, books, and even their own conference. And they improved their docs throughout the years significantly. However, the API documentation is not ideal. Whenever I want to find a command to rename a library or delete it, I struggle to find anything in their doc. And it's usually faster for me to just google it or even do it manually (don't do it, though). It would be good to have the page with the most common commands because, honestly, it's all you need 90% of the time, yet there's none. Or I couldn't find it, which isn't speaking in favor of the docs as well.&lt;/p&gt;

&lt;p&gt;The next struggle is not a big issue anymore, but it was previously. I'm talking about low-level access to the webpack config. I think Angular started this trend, and NX developers followed it for some reason. Maybe it's their Angular roots. I don't know. It was a painful to get to the config. We had to use &lt;a href="https://github.com/ds300/patch-package"&gt;patch-package&lt;/a&gt; util to overwrite config directly inside the node_modules folder to make the change we needed. Luckily it's not the case anymore. You can provide a custom webpack config per application without needing a 3rd party package.&lt;/p&gt;

&lt;p&gt;The NX team follows the single-version policy. Meaning if you need to maintain several different versions of the same dependency, you better look elsewhere. I think it's one of the rare cases, but we totally had it. On one of the projects, we used an in-house package that required a specific version of React. But in our repo, we already moved on to a newer version. Although I think some hacks might help you achieve it, we couldn't make it work for us. Likely we could convince the team that maintained the package to put the upgrade in their roadmap sooner. However, it could quickly become a serious problem for us.&lt;/p&gt;

&lt;p&gt;Last but not least, and maybe the most prominent issue with monorepos, is bloating of the sources. Besides all the boilerplate files, you basically cram all of your projects into a single repo. It can and will affect your install time and your build time. Currently, in our project, it takes 20 minutes to release a version. And it's for a frontend app and without tests! About 7 minutes takes to install all dependencies which might not be relevant to the app we're about to release. And about the same time to run the build command. Plus a bunch of other smaller scripts. In our case, it's manageable: we're going to reduce the number of dependencies as we get rid of the legacy. Also, we're still running node 12, which is way slower than 16 in terms of npm install. Although those issues are partially on our side, I imagine it wouldn't be so drastic in polyrepo architecture.&lt;/p&gt;

&lt;p&gt;By the way, fun trivia: Google runs all their codebase in a single monorepo that contains 2 billion lines of code representing 86 Tb of storage. You can read more about it &lt;a href="https://qeunit.com/blog/how-google-does-monorepo/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;As I started learning and using more technologies, people asked me what I liked better: the framework I used before or the one I'm using now. I always answer: it doesn't matter to me. A tool is a tool. But the more you use a tool, the more familiar you get with it and more proficient. And after some time, you would prefer your current tool over others, maybe not because you like it the most, but because you're more comfortable with it. It becomes your preference.&lt;/p&gt;

&lt;p&gt;I know there's always debate over the right tool for a job, but the truth is most of the time, it comes down to preference and resource availability.&lt;/p&gt;

&lt;p&gt;It's not always unicorns and rainbows with NX. But it has proven to be an excellent tool for various projects. I know I'll most likely use it in my next project. It became my preference.&lt;/p&gt;

&lt;p&gt;I invite you to read more about it, to be aware of such a tool. Maybe you would also want to try it in your next project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nx.dev/"&gt;nx.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qeunit.com/blog/how-google-does-monorepo/"&gt;How google does monorepo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://research.google/pubs/pub45424/"&gt;Why Google Stores Billions of Lines of Code in a Single Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/joelparkerhenderson/monorepo-vs-polyrepo"&gt;Monorepo vs Polyrepo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://monorepo.tools/"&gt;monorepo.tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/korfuri/awesome-monorepo"&gt;Awesome monorepos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;I'd like to thank &lt;a class="mentioned-user" href="https://dev.to/eransakal"&gt;@eransakal&lt;/a&gt; and &lt;a class="mentioned-user" href="https://dev.to/amirch1"&gt;@amirch1&lt;/a&gt; for their feeback. Check out Eran's &lt;a href="https://sakalim.com"&gt;blog&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  #StandWithUkraine 🇺🇦
&lt;/h2&gt;

&lt;p&gt;It's been 5 months since russia waged a full-scale war against my homeland. We're still strong, fighting, and will continue to fight until our victory. Stand with Ukraine and support us.&lt;br&gt;
The best way is to donate to those charity foundations: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://savelife.in.ua/en/donate-en/"&gt;Come back alive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://prytulafoundation.org/en/home/support_page"&gt;Serhiy Prytula Charity Foundation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every penny counts!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
      <category>devops</category>
    </item>
    <item>
      <title>RxJS Operators decision table</title>
      <dc:creator>Stas Kohut</dc:creator>
      <pubDate>Fri, 11 Dec 2020 09:25:19 +0000</pubDate>
      <link>https://dev.to/diamonddarrell/rxjs-operators-decision-table-44j8</link>
      <guid>https://dev.to/diamonddarrell/rxjs-operators-decision-table-44j8</guid>
      <description>&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1039590397943705602-300" src="https://platform.twitter.com/embed/Tweet.html?id=1039590397943705602"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1039590397943705602-300');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1039590397943705602&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I like this joke yet I think it's obsolete.&lt;br&gt;
I remember myself 4 years ago trying to comprehend all the concepts behind reactive programming, learning ways to write my streams and manipulate them using operators. It wasn't easy besides you had to keep up with all new changes (and there're a few of them). But today RxJS is a mature toolchain with a lot of learning materials, the amount of effort the team puts into making the library more accessible for common folks like me is truly impressive.&lt;/p&gt;

&lt;p&gt;Yet it's still a common opinion that RxJS is not very friendly for newbies. Besides core concepts of reactive programming (that are not specific to RxJS), the number of operators available for a user might be intimidating.&lt;br&gt;
As I stated above, the maintainers' team did and doing a great job simplifying and improving the API. And luckily we don't need to remember all of them as a tiny portion is actually needed for everyday use.&lt;/p&gt;

&lt;p&gt;Still, you can find yourself a bit lost thinking of what operator should I use in certain cases. Don't worry the docs got you covered, it contains a super useful operator decision tree util &lt;a href="https://rxjs.dev/operator-decision-tree" rel="noopener noreferrer"&gt;https://rxjs.dev/operator-decision-tree&lt;/a&gt;. Answering simple question about your intentions with the stream it can suggest the most fitting operator for your case.&lt;/p&gt;

&lt;p&gt;It's great, but I prefer the table view of the same tree. And unsurprisingly there's such a table &lt;a href="https://xgrommx.github.io/rx-book/content/which_operator_do_i_use/index.html" rel="noopener noreferrer"&gt;https://xgrommx.github.io/rx-book/content/which_operator_do_i_use/index.html&lt;/a&gt;, but there's another "but" – it's a bit outdated thus I present you the up-to-date (at the time of writing this post) version of the same table:&lt;/p&gt;
&lt;h1&gt;
  
  
  Creation operators
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;td rowspan="16"&gt;I want to create a new sequence&lt;/td&gt;
    &lt;td rowspan="2"&gt;using custom logic&lt;/td&gt;
    &lt;td colspan="2"&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/class/Observable#create" rel="noopener noreferrer"&gt;Observable (class)&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;that works like a for-loop&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/generate" rel="noopener noreferrer"&gt;generate&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;that throws an error&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/throwError" rel="noopener noreferrer"&gt;throwError&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;that completes&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/const/EMPTY" rel="noopener noreferrer"&gt;EMPTY (const)&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;that never does anything&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/const/NEVER" rel="noopener noreferrer"&gt;NEVER (const)&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;from an event&lt;/td&gt;
    &lt;td colspan="2"&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/fromEvent" rel="noopener noreferrer"&gt;fromEvent&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;that uses custom functions to add and remove event handlers&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/fromEventPattern" rel="noopener noreferrer"&gt;fromEventPattern&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="4"&gt;&lt;/td&gt;
    &lt;td&gt;over the values in an array&lt;/td&gt;
    &lt;td&gt;of object key/values&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/pairs" rel="noopener noreferrer"&gt;pairs&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;over values in a numeric range&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/range" rel="noopener noreferrer"&gt;range&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;over the values in an iterable, a Promise, array or array-like object&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/from" rel="noopener noreferrer"&gt;from&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;over arguments&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/of" rel="noopener noreferrer"&gt;of&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;that emits values on a timer&lt;/td&gt;
    &lt;td colspan="2"&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/interval" rel="noopener noreferrer"&gt;interval&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;with an optional initial delay&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/timer" rel="noopener noreferrer"&gt;timer&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;decided at subscribe-time&lt;/td&gt;
    &lt;td colspan="2"&gt;based on a boolean condition&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/iif" rel="noopener noreferrer"&gt;iif&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;using custom logic&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/defer" rel="noopener noreferrer"&gt;defer&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;that depends on a resource&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/using" rel="noopener noreferrer"&gt;using&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="7"&gt;I want to combine multiple sequences&lt;/td&gt;
    &lt;td colspan="3"&gt;and only receive values from the sequence that yields a value first&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/race" rel="noopener noreferrer"&gt;race&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;and be notified when all of them have finished&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/forkJoin" rel="noopener noreferrer"&gt;forkJoin&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;and output the values from all of them&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/merge" rel="noopener noreferrer"&gt;merge&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;in order&lt;/td&gt;
    &lt;td colspan="2"&gt;reusing the latest value when unchanged&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/combineLatest" rel="noopener noreferrer"&gt;combineLatest&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;using each value only once&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/zip" rel="noopener noreferrer"&gt;zip&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;by subscribing to each in order&lt;/td&gt;
    &lt;td colspan="2"&gt;when the previous sequence completes&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/concat" rel="noopener noreferrer"&gt;concat&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;regardless of whether the previous sequence completes or errors&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/onErrorResumeNext" rel="noopener noreferrer"&gt;onErrorResumeNext&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h1&gt;
  
  
  Stream operators (ex instance operators)
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;td rowspan="69"&gt;
    &lt;span&gt;Using an existing sequence&lt;/span&gt;
    &lt;/td&gt;
    &lt;td colspan="3"&gt;I want to change each value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/map" rel="noopener noreferrer"&gt;map&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;I want to pull a property off each value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/pluck" rel="noopener noreferrer"&gt;pluck&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;I want to be notified of values without affecting them&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/tap" rel="noopener noreferrer"&gt;tap&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="5"&gt;I want to include values&lt;/td&gt;
    &lt;td colspan="2"&gt;based on custom logic&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/filter" rel="noopener noreferrer"&gt;filter&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;from the start of the sequence&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/take" rel="noopener noreferrer"&gt;take&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on custom logic&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/takeWhile" rel="noopener noreferrer"&gt;takeWhile&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;from the end of the sequence&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/takeLast" rel="noopener noreferrer"&gt;takeLast&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;until another sequence emits a value or completes&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/takeUntil" rel="noopener noreferrer"&gt;takeUntil&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="14"&gt;I want to ignore values&lt;/td&gt;
    &lt;td colspan="2"&gt;altogether&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/ignoreElements" rel="noopener noreferrer"&gt;ignoreElements&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;from the start of the sequence&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/skip" rel="noopener noreferrer"&gt;skip&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on custom logic&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/skipWhile" rel="noopener noreferrer"&gt;skipWhile&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;from the end of the sequence&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/skipLast" rel="noopener noreferrer"&gt;skipLast&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;until another sequence emits a value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/skipUntil" rel="noopener noreferrer"&gt;skipUntil&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;that have the same value as the previous&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/distinctUntilChanged" rel="noopener noreferrer"&gt;distinctUntilChanged&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on object by key&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/distinctUntilKeyChanged" rel="noopener noreferrer"&gt;distinctUntilKeyChanged&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;by selector&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/distinct" rel="noopener noreferrer"&gt;distinct&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;that occur too frequently&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/throttle" rel="noopener noreferrer"&gt;throttle&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on duration&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/throttleTime" rel="noopener noreferrer"&gt;throttleTime&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;by emitting the first value in each time window &lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/debounce" rel="noopener noreferrer"&gt;debounce&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on due time&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/debounceTime" rel="noopener noreferrer"&gt;debounceTime&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;by emitting the last value in each time window &lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/audit" rel="noopener noreferrer"&gt;audit&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on due time&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/auditTime" rel="noopener noreferrer"&gt;auditTime&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;I want to compute&lt;/td&gt;
    &lt;td rowspan="3"&gt;using custom logic&lt;/td&gt;
    &lt;td&gt;and only output the final value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/reduce" rel="noopener noreferrer"&gt;reduce&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;and output the values as they are calculated&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/scan" rel="noopener noreferrer"&gt;scan&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;and output observables as they are calculated&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/mergeScan" rel="noopener noreferrer"&gt;mergeScan&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;I want to wrap its messages with metadata&lt;/td&gt;
    &lt;td colspan="2"&gt;that describes each message&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/materialize" rel="noopener noreferrer"&gt;materialize&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;that includes the time past since the last value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/timeInterval" rel="noopener noreferrer"&gt;timeInterval&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;that includes a timestamp&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/timestamp" rel="noopener noreferrer"&gt;timestamp&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;after a period of inactivity&lt;/td&gt;
    &lt;td colspan="2"&gt;I want to throw an error&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/timeout" rel="noopener noreferrer"&gt;timeout&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;I want to switch to another sequence&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/timeoutWith" rel="noopener noreferrer"&gt;timeoutWith&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;I want ensure there is only one value&lt;/td&gt;
    &lt;td colspan="2"&gt;and throw an error if there are more or less than one value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/single" rel="noopener noreferrer"&gt;single&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;I want to only take the first value&lt;/td&gt;
    &lt;td colspan="2"&gt;and throw an error if there are no values&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/first" rel="noopener noreferrer"&gt;first&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;within a time period&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/sample" rel="noopener noreferrer"&gt;sample&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on period&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/sampleTime" rel="noopener noreferrer"&gt;sampleTime&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;I want to only take the last value&lt;/td&gt;
    &lt;td colspan="2"&gt;and error if there are no values&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/last" rel="noopener noreferrer"&gt;last&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;I want to know how many values it contains&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/count" rel="noopener noreferrer"&gt;count&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td colspan="2"&gt;by all of its values&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/every" rel="noopener noreferrer"&gt;every&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2" rowspan="2"&gt;I want to delay messages by a specific amount of time&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/delay" rel="noopener noreferrer"&gt;delay&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on custom logic&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/delayWhen" rel="noopener noreferrer"&gt;delayWhen&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="10"&gt;I want to group the values&lt;/td&gt;
    &lt;td colspan="2"&gt;until the sequence completes&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/toArray" rel="noopener noreferrer"&gt;toArray&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;using custom logic&lt;/td&gt;
    &lt;td&gt;as arrays&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/buffer" rel="noopener noreferrer"&gt;buffer&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;as sequences&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/window" rel="noopener noreferrer"&gt;window&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;in batches of a particular size&lt;/td&gt;
    &lt;td&gt;as arrays&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/bufferCount" rel="noopener noreferrer"&gt;bufferCount&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;as sequences&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/windowCount" rel="noopener noreferrer"&gt;windowCount&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;based on time&lt;/td&gt;
    &lt;td&gt;as arrays&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/bufferTime" rel="noopener noreferrer"&gt;bufferTime&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;as sequences&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/windowTime" rel="noopener noreferrer"&gt;windowTime&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;based on observable&lt;/td&gt;
    &lt;td&gt;as arrays&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/bufferWhen" rel="noopener noreferrer"&gt;bufferWhen&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;as sequences&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/windowWhen" rel="noopener noreferrer"&gt;windowWhen&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on a key&lt;/td&gt;
    &lt;td&gt;until the sequence completes&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/groupBy" rel="noopener noreferrer"&gt;groupBy&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="4"&gt;I want to start a new sequence for each value&lt;/td&gt;
    &lt;td colspan="2"&gt;and emit the values from all sequences in parallel&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/mergeMap" rel="noopener noreferrer"&gt;mergeMap&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and emit the values from each sequence in order&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/concatMap" rel="noopener noreferrer"&gt;concatMap&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and cancel the previous sequence when a new value arrives&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/switchMap" rel="noopener noreferrer"&gt;switchMap&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and recursively start a new sequence for each new value&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/expand" rel="noopener noreferrer"&gt;expand&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;I want to combine it with another&lt;/td&gt;
    &lt;td colspan="2"&gt;And be notified when both have completed&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/forkJoin" rel="noopener noreferrer"&gt;forkJoin&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="6"&gt;I want to share a subscription between multiple subscribers&lt;/td&gt;
    &lt;td colspan="2"&gt;using a specific subject implementation&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/multicast" rel="noopener noreferrer"&gt;multicast&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and start it as soon as first subscriber arrives&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/share" rel="noopener noreferrer"&gt;share&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and start it manually or imperatively&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/publish" rel="noopener noreferrer"&gt;publish&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and supply the last value to future subscribers&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/publishLast" rel="noopener noreferrer"&gt;publishLast&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and replay a default or the latest value to future subscribers&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/publishBehavior" rel="noopener noreferrer"&gt;publishBehavior&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;and replay n number of values to future subscribers&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/publishReplay" rel="noopener noreferrer"&gt;publishReplay&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;when an error occurs&lt;/td&gt;
    &lt;td rowspan="2"&gt;I want to re-subscribe&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/retry" rel="noopener noreferrer"&gt;retry&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;based on custom logic&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/retryWhen" rel="noopener noreferrer"&gt;retryWhen&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;I want to start a new sequence&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/catchError" rel="noopener noreferrer"&gt;catchError&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;when it completes&lt;/td&gt;
    &lt;td colspan="2"&gt;I want to re-subscribe&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/repeat" rel="noopener noreferrer"&gt;repeat&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;I want to start a new sequence&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/concat" rel="noopener noreferrer"&gt;concat&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;when it completes or errors&lt;/td&gt;
    &lt;td colspan="2"&gt;I want to start a new sequence&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/onErrorResumeNext" rel="noopener noreferrer"&gt;onErrorResumeNext&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;when it completes, errors or unsubscribes&lt;/td&gt;
    &lt;td colspan="2"&gt;I want to execute a function&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/finalize" rel="noopener noreferrer"&gt;finalize&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;I want to change the scheduler that routes&lt;/td&gt;
    &lt;td colspan="2"&gt;calls to subscribe&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/subscribeOn" rel="noopener noreferrer"&gt;subscribeOn&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="2"&gt;messages&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/observeOn" rel="noopener noreferrer"&gt;observeOn&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="6"&gt;Using two sequences&lt;/td&gt;
    &lt;td&gt;I want to decide which to receive values from&lt;/td&gt;
    &lt;td colspan="2"&gt;based on which one has values first&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/race" rel="noopener noreferrer"&gt;race&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;I want to determine if their values are equal&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/sequenceEqual" rel="noopener noreferrer"&gt;sequenceEqual&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="3"&gt;I want to combine their values&lt;/td&gt;
    &lt;td colspan="2"&gt;only when the first sequence emits, using the latest value from each&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/withLatestFrom" rel="noopener noreferrer"&gt;withLatestFrom&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td rowspan="2"&gt;in order&lt;/td&gt;
    &lt;td&gt;reusing the latest value when unchanged&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/operators/combineLatest" rel="noopener noreferrer"&gt;combineLatest&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;using each value only once&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/zip" rel="noopener noreferrer"&gt;zip&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;I want to include values from both&lt;/td&gt;
    &lt;td&gt;&lt;a href="https://rxjs.dev/api/index/function/merge" rel="noopener noreferrer"&gt;merge&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you're new to RxJS be sure to check out Eran's beginner guide post &lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/eransakal" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F304933%2F28033c0d-db97-41c7-8a77-aae5728b8198.jpeg" alt="eransakal"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/eransakal/understanding-rxjs-learn-from-examples-part-1-3m76" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Understanding RxJS - Learn From Examples - Part 1&lt;/h2&gt;
      &lt;h3&gt;Eran Sakal ・ Jun 30 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rxjs&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#angular&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Keep hacking my dudes&lt;/em&gt; 😉&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>rxjs</category>
    </item>
  </channel>
</rss>
