<?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: Logan</title>
    <description>The latest articles on DEV Community by Logan (@lgpage).</description>
    <link>https://dev.to/lgpage</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%2F1006740%2Fb5be4cab-d127-4cc9-b89b-68b4a2de6bb9.jpeg</url>
      <title>DEV Community: Logan</title>
      <link>https://dev.to/lgpage</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lgpage"/>
    <language>en</language>
    <item>
      <title>Introducing RxTutor - An interactive sandbox for RxJS observables</title>
      <dc:creator>Logan</dc:creator>
      <pubDate>Fri, 13 Jan 2023 06:32:12 +0000</pubDate>
      <link>https://dev.to/lgpage/introducing-rxtutor-an-interactive-sandbox-for-rxjs-observables-49mb</link>
      <guid>https://dev.to/lgpage/introducing-rxtutor-an-interactive-sandbox-for-rxjs-observables-49mb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--emvthETu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eaidno29s1on4on6vtfs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--emvthETu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eaidno29s1on4on6vtfs.gif" alt="Example usage of RxTutor to visualize the RxJS switchMap operator" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rxtutor.org"&gt;RxTutor&lt;/a&gt; (inspired by &lt;a href="https://rxmarbles.com"&gt;RxMarbles&lt;/a&gt;) is an online interactive sandbox for visualizing &lt;a href="https://rxjs.dev"&gt;RxJS&lt;/a&gt; observables. &lt;a href="https://rxtutor.org"&gt;RxTutor&lt;/a&gt; is interactive like &lt;a href="https://rxmarbles.com/"&gt;RxMarbles&lt;/a&gt; in that you can drag the nodes of the input observables to see how the output observable changes. &lt;a href="https://rxtutor.org"&gt;RxTutor&lt;/a&gt; has the added functionality of being able to change the input observable parameters as well as change the code for creating the output observable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rxtutor.org"&gt;RxTutor&lt;/a&gt; has a range of examples added as starting points for change and playing around.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x4_cGjxu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ektdslc8ffj8pjmzhonn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x4_cGjxu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ektdslc8ffj8pjmzhonn.png" alt="The RxTutor switchMap exampleRxJS Tutor" width="880" height="472"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://rxtutor.org/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--jgFoTplF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://rxtutor.org/assets/rxtutor-og.png" height="441" class="m-0" width="880"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://rxtutor.org/" rel="noopener noreferrer" class="c-link"&gt;
          RxTutor
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          An interactive sandbox for RxJS Observables
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fj3mxqNW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://rxtutor.org/favicon.ico" width="48" height="48"&gt;
        rxtutor.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Why was RxTutor Created?
&lt;/h2&gt;

&lt;p&gt;When I started out learning RxJS, RxMarbles was invaluable in helping me understand how each of the RxJS operators behaved. Further down the line, as I started implementing RxJS in code, I quickly got to a point where I struggled to understand / internally visualize how a combination of operators would behave or how the RxMarbles example tied up to a more concrete example with say a different number of emitted values or different point of completion.&lt;/p&gt;

&lt;p&gt;And so the idea of RxTutor was born. I wanted to be able to visualize RxJS observables while being able to change the input observables (their emitted values, their number of emitted values, how they complete or error, etc.) as well as being able to combine multiple RxJS operators to generate the output observable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Input Observables
&lt;/h2&gt;

&lt;p&gt;RxTutor allows adding up to three observables as input to the visualization code. Each input observable has nodes (including an optional complete or error node) that can be dragged to different frames to see how the output observable changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LvqFfLFS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f2584kszoku3x8qjgyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LvqFfLFS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f2584kszoku3x8qjgyh.png" alt="Example input nodes for visualizing RxJS operators" width="880" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next nodes are visualized as circles (with the emitted value shown in the centre), while the complete node is visualized as a pipe (|), and the error node is visualized as a cross (X).&lt;br&gt;
Each input observable can be configured via its gear icon, which brings up a stream options modal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MBT1LhK7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aglbu3capb380xu6c28p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MBT1LhK7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aglbu3capb380xu6c28p.png" alt="Input observable stream options modal" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Visualization Code
&lt;/h2&gt;

&lt;p&gt;The visualize method has four arguments, the first being RxJS, the second, third and fourth being the input observables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;visualize&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;switchMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tap&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;one$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;two$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;three$&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;one$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;switchMap&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;two$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment"&gt;Destructuring assignment syntax&lt;/a&gt; is used, in the RxTutor examples, for unpacking the required RxJS operators used with the input observables to return the output observable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Output Observable
&lt;/h2&gt;

&lt;p&gt;The output observable is created from the input observables and RxJS operators used in the visualize method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1WTC-LEq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c7mhwszmcn1sdca10uu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1WTC-LEq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c7mhwszmcn1sdca10uu.png" alt="Example output observable for the switchMap operator" width="880" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the output values are small (less than 3 characters) then they are displayed directly, else a marble symbol is shown. The marble diagram (along with the values) for each observable can be copied to the clipboard via the information icon.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'-AB-C--DE-F----|',
{
  "A": "1a",
  "B": "2a",
  "C": "2b",
  "D": "3a",
  "E": "4a",
  "F": "4b"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Contribute
&lt;/h2&gt;

&lt;p&gt;If you find a bug, have a feature suggestion, or would like to contribute to &lt;a href="https://rxtutor.org"&gt;RxTutor&lt;/a&gt;, then feel free to visit the &lt;a href="https://github.com/lgpage/rxtutor"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/lgpage"&gt;
        lgpage
      &lt;/a&gt; / &lt;a href="https://github.com/lgpage/rxtutor"&gt;
        rxtutor
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An interactive sandbox for RxJS Observables
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Rxtutor&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.com/lgpage/rxtutor/actions/workflows/lint-test-build-pull-request.yml?query=branch%3Amain"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O1By2xBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/lgpage/rxtutor/actions/workflows/lint-test-build-pull-request.yml/badge.svg%3Fbranch%3Dmain" alt="ci badge"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/lgpage/rxtutor" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/437c736e960cc646606ee47313f2def881d1dac4c7c515546d3fef520d45bdbd/68747470733a2f2f636f6465636f762e696f2f67682f6c67706167652f72787475746f722f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4f49766d446b6e507638" alt="codecov"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://rxtutor.org" rel="nofollow"&gt;https://rxtutor.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An interactive sandbox for RxJS Observables&lt;/p&gt;
&lt;p&gt;&lt;a href="https://rxtutor.org/mergeMap" rel="nofollow"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rYGnwPz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/lgpage/rxtutor./src/assets/rxtutor-og.png" alt="Usage Example"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/lgpage/rxtutor"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



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