<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>angular | Kate Gable</title>
	<atom:link href="https://www.katesky.com/tag/angular/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.katesky.com</link>
	<description>sharing knowledge, encouraging to learn, promoting passion for coding, supporting mothers who code</description>
	<lastBuildDate>Tue, 20 Dec 2022 21:29:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
<site xmlns="com-wordpress:feed-additions:1">193364748</site>	<item>
		<title>Data polling with ngrx effect and how to unit test it</title>
		<link>https://www.katesky.com/2022/12/20/data-polling-with-ngrx-effect-and-how-to-unit-test-it/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=data-polling-with-ngrx-effect-and-how-to-unit-test-it</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Tue, 20 Dec 2022 18:30:11 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<category><![CDATA[effects]]></category>
		<category><![CDATA[kate sky]]></category>
		<category><![CDATA[ngrx]]></category>
		<category><![CDATA[state management]]></category>
		<category><![CDATA[TestScheduler]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=260</guid>

					<description><![CDATA[<p>I just finished implementing data polling using ngrx effects. For those unfamiliar with ngrx, it is a popular library for implementing the Redux pattern in Angular applications. To implement data polling with ngrx effects, you can create an effect that listens for <br /><a href="https://www.katesky.com/2022/12/20/data-polling-with-ngrx-effect-and-how-to-unit-test-it/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2022/12/20/data-polling-with-ngrx-effect-and-how-to-unit-test-it/">Data polling with ngrx effect and how to unit test it</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<p>I just finished implementing data polling using ngrx effects. For those unfamiliar with ngrx, it is a popular library for implementing the Redux pattern in Angular applications.</p>



<p>To implement data polling with ngrx effects, you can create an effect that listens for a specific action, such as a <code>POLL_DATA</code> action. When this action is dispatched, the effect can perform an HTTP request to retrieve the data from a remote server, and then dispatch a new action with the data.</p>



<p>You can use the <code>@Effect</code> decorator to create an effect that listens for specific actions. The <code>@Effect</code> decorator takes an options object as an argument, which allows you to specify the action that the effect should listen for and the effect’s behavior.</p>



<p>For example, you might create an effect that listens for the <code>POLL_DATA</code> action and performs an HTTP request to retrieve the data like this:</p>


<div class="wp-block-syntaxhighlighter-code code"><pre class="brush: jscript; highlight: [1]; title: ; notranslate">
@Injectable()
export class PollingEffects {
  pollData$: Observable&lt;Action&gt; = this.actions$.pipe(
    ofType(POLL_DATA),
    switchMap(() =&gt;
      this.http.get('/api/data').pipe(
        map((data) =&gt; ({ type: DATA_RECEIVED, payload: data })),
        catchError(() =&gt; of({ type: DATA_REQUEST_FAILED }))
      )
    )
  );
}


</pre></div>


<p>This effect listens for the <code>POLL_DATA</code> action and then performs an HTTP request using the <code>HttpClient</code> service. If the request is successful, it dispatches a <code>DATA_RECEIVED</code> action with the received data as the payload. If the request fails, it dispatches a <code>DATA_REQUEST_FAILED</code> action.</p>



<p>To ensure that the data is polled at regular intervals, you can use the <code>interval</code> operator from the RxJS library. You can modify the effect above to poll the data every 10 seconds like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
@Injectable()
export class PollingEffects {
  pollData$: Observable&lt;Action&gt; = this.actions$.pipe(
    ofType(POLL_DATA),
    switchMap(() =&gt; interval(10000)),
    switchMap(() =&gt;
      this.http.get('/api/data').pipe(
        map((data) =&gt; ({ type: DATA_RECEIVED, payload: data })),
        catchError(() =&gt; of({ type: DATA_REQUEST_FAILED }))
      )
    )
  );
}

</pre></div>


<p>In this modified version of the effect, the <code>interval</code> operator is used to emit a value every 10 seconds (10000 milliseconds). The effect then uses the <code>switchMap</code> operator to perform an HTTP request every time the interval emits a value.</p>



<p>To stop the data polling, you can simply dispatch a new action that the effect can listen for and respond to.</p>



<p>For example, you might create a <code>STOP_POLLING</code> action that the effect can listen for and use to stop polling the data. You can modify the effect above to stop polling when the <code>STOP_POLLING</code> action is dispatched like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
@Injectable()
export class PollingEffects {
  pollData$: Observable&lt;Action&gt; = this.actions$.pipe(
    ofType(POLL_DATA),
    switchMap(() =&gt;
      interval(10000).pipe(takeUntil(this.actions$.pipe(ofType(STOP_POLLING))))
    ),
    switchMap(() =&gt;
      this.http.get('/api/data').pipe(
        map((data) =&gt; ({ type: DATA_RECEIVED, payload: data })),
        catchError(() =&gt; of({ type: DATA_REQUEST_FAILED }))
      )
    )
  );
}
</pre></div>


<p>In this modified version of the effect, the <code>takeUntil</code> operator is used to stop the data polling when the <code>STOP_POLLING</code> action is dispatched. The <code>takeUntil</code> operator takes an observable as an argument and completes the source observable (in this case, the <code>interval</code> observable) when the argument observable emits a value.</p>



<p>To use this modified effect, you can dispatch the <code>POLL_DATA</code> action to start polling and the <code>STOP_POLLING</code> action to stop polling.</p>



<h4 class="wp-block-heading">To create a unit test for the data polling effect using the TestScheduler from the RxJS library, you can use the following steps: </h4>



<p>First you have to modify your effect to use asyncScheduler like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
@Injectable()
export class PollingEffects {
  pollData$: Observable&amp;lt;Action&gt; = this.actions$.pipe(
    ofType(POLL_DATA),
    switchMap(() =&gt;
      interval(10000, asyncScheduler).pipe(
        takeUntil(this.actions$.pipe(ofType(STOP_POLLING)))
      )
    ),
    switchMap(() =&gt;
      this.http.get('/api/data').pipe(
        map((data) =&gt; ({ type: DATA_RECEIVED, payload: data })),
        catchError(() =&gt; of({ type: DATA_REQUEST_FAILED }))
      )
    )
  );
}

</pre></div>


<p>In this modified version of the effect, the <code>interval</code> operator is called with the <code>asyncScheduler</code> as the second argument. This causes the interval to use the <code>asyncScheduler</code> to schedule its emissions.</p>



<p>The <code>asyncScheduler</code> is a scheduler that schedules work asynchronously, using the JavaScript <code>interval</code> function. This can be useful if you want to simulate a delay in the data polling effect, or if you want to ensure that the effect is run outside the Angular zone.</p>



<p>I hope this helps clarify how to use the <code>asyncScheduler</code> with the data polling effect. Next you will add your unit tests file and follow the steps:</p>



<ol class="has-small-font-size wp-block-list">
<li>Import the <code>TestScheduler</code> from the RxJS library. The <code>TestScheduler</code> is used to control the virtual time in the test;</li>



<li>Create an instance of the <code>TestScheduler</code> and set up the test actions and expected results. To do this, you will need to define the actions that the effect should listen for and the expected results of the effect. </li>



<li>Set up the dependencies for the effect under test. This will typically include any services or dependencies that the effect uses, such as the <code>HttpClient</code> service. You can use mock implementations of these dependencies to control their behavior in the test.</li>



<li>Create an instance of the effect under test and pass in the dependencies.</li>



<li>Pass <code>TestScheduler</code> instance into the effect that is under test. This will execute the effect with a virtual timer.</li>
</ol>



<p>Here is an example of a unit test for the data polling effect using the TestScheduler:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
@Injectable()
export class PollingEffects {

    pollData$ = createEffect(() =&gt; ({ scheduler = asyncScheduler} = {}) =&gt;
    this.actions$.pipe(
      ofType(POLL_DATA),
      switchMap(() =&gt; interval(10000, asyncScheduler).pipe(
        takeUntil(this.actions$.pipe(ofType(STOP_POLLING)))
      )),
      switchMap(() =&gt; this.http.get('/api/data').pipe(
        map(data =&gt; ({ type: DATA_RECEIVED, payload: data })),
        catchError(() =&gt; of({ type: DATA_REQUEST_FAILED }))
      ))
    )
  );

}

</pre></div>


<p>To use the <code>createEffect</code> function from the ngrx library with the data polling effect, you can modify the effect like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">

</pre></div>


<p>The <code>createEffect</code> function takes a function that returns an observable as an argument, and returns an observable of actions. The function that is passed to <code>createEffect</code> should contain the logic for the effect.</p>



<p>In this modified version of the effect, the <code>createEffect</code> function is used to wrap the logic for the effect in a way that is compatible with the ngrx store. The effect listens for the <code>POLL_DATA</code> action and performs an HTTP request to retrieve the data every 10 seconds (10000 milliseconds) using asyncScheduler.  If the request is successful, it dispatches a <code>DATA_RECEIVED</code> action with the received data as the payload. If the request fails, it dispatches a <code>DATA_REQUEST_FAILED</code> action.</p>



<p>I hope this helps clarify how to use the <code>createEffect</code> function with the data polling effect. </p>



<p></p>



<p>Using ngrx effects to implement data polling is a straightforward process. Essentially, you can create an effect that listens for a specific action, such as a <code>POLL_DATA</code> action, and performs an HTTP request to retrieve data from a remote server. The effect can then dispatch a new action, such as a <code>DATA_RECEIVED</code> action, with the received data as the payload.</p>



<p>To stop the data polling, you can simply dispatch a new action, such as a <code>STOP_POLLING</code> action, that the effect can listen for and use to stop the data polling process.</p>



<p>Unit testing this effect is a bit tricky but you got it!</p>



<p>Hope all the code examples help you!</p>



<p>Hope you enjoyed this article.</p>



<p></p>



<p></p>



<pre class="wp-block-preformatted"></pre>
</body>The post <a href="https://www.katesky.com/2022/12/20/data-polling-with-ngrx-effect-and-how-to-unit-test-it/">Data polling with ngrx effect and how to unit test it</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">260</post-id>	</item>
		<item>
		<title>Better ways to share data between components.</title>
		<link>https://www.katesky.com/2021/02/18/better-ways-to-share-data-between-components/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=better-ways-to-share-data-between-components</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Thu, 18 Feb 2021 09:25:00 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=218</guid>

					<description><![CDATA[<p>Sharing data in the Angular application When it comes to sharing data between components in an Angular application we have to remember that there more than one right way to do it! Let’s go over some assumptions, rules, and considerations for this <br /><a href="https://www.katesky.com/2021/02/18/better-ways-to-share-data-between-components/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2021/02/18/better-ways-to-share-data-between-components/">Better ways to share data between components.</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<h3 class="wp-block-heading">Sharing data in the Angular application</h3>



<p>When it comes to sharing data between components in an Angular application we have to remember that there more than one right way to do it!</p>



<p> Let’s go over some assumptions, rules, and considerations for this article.</p>



<p><strong>Consider</strong>: Follow a container presenter pattern. Check out my video on this <a href="https://youtu.be/d4fU0A0_oCI" target="_blank" rel="noreferrer noopener" title="Youtube link to AngualrAir meetup">here</a>.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="jetpack-video-wrapper"><iframe title="AngularAir - Clean code with Container Presenter Pattern with Kate Sky" width="640" height="360" src="https://www.youtube.com/embed/d4fU0A0_oCI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>



<p>Your components have as little responsibility as possible; whether it is to get data from the server or just display it. </p>



<p>You create dumb components whenever possible.</p>



<p>You keep your dependency injections in the components to a minimum.</p>



<p>You abstract business logic to the services.</p>



<p><strong>Assumptions</strong>: You don’t always have the luxury of adding a state management library to your application. </p>



<p>I used NGRX and I know that it is a complex library and if the whole team is not on board to use it, then your code becomes a mish-mash of different approaches. </p>



<p>Get the whole team to commit to a state management library or go with another approach like the one described here.</p>



<p><strong>Rules</strong>: Keep application performance at the top of the priority list.</p>



<p>Your code has to be clean and easy to read and maintain.</p>



<h2 class="wp-block-heading">Say No to bubbling up events.</h2>



<p>Here is an example of 3 components that all produce data. They have no access to the data they create. Events bubble up to the app.component. </p>



<p><strong>I want to show you what NOT to do!</strong></p>



<p>checkout StackBlitz:</p>



<p><a href="https://stackblitz.com/github/katesky/messages-sent-app" target="_blank" rel="noreferrer noopener" title="bad code">https://stackblitz.com/github/katesky/messages-sent-app</a></p>



<p>Next up is code where we will add a service that will manage our data and it will be shared with all of our components.</p>



<h2 class="wp-block-heading">Use service with a subject</h2>



<p>git checkout with-service or go to code here –&gt; <a href="https://stackblitz.com/github/katesky/messages-sent-app/tree/with-service" target="_blank" rel="noreferrer noopener" title="new branch">new branch</a></p>



<p>We will create a service that will hold a list of our data in a private BehaviorSubject of type an array of strings.</p>



<p>We will add a public observable of that BehaviorSubject to our service.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="164" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?resize=640%2C164&#038;ssl=1" alt="" class="wp-image-219" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?resize=1024%2C262&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?resize=300%2C77&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?resize=768%2C196&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?resize=1536%2C393&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?w=1548&amp;ssl=1 1548w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic1.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Now we can add a function that will mutate our data.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="229" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?resize=640%2C229&#038;ssl=1" alt="" class="wp-image-220" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?resize=1024%2C366&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?resize=300%2C107&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?resize=768%2C275&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?resize=1536%2C549&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?w=1694&amp;ssl=1 1694w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic2.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>We now have a central area where our data is held.</p>



<p>It can be shared across all of our components and there are no events that have to be emitted up to the parents’ components.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="283" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?resize=640%2C283&#038;ssl=1" alt="" class="wp-image-221" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?resize=1024%2C453&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?resize=300%2C133&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?resize=768%2C340&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?resize=1536%2C680&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?w=1564&amp;ssl=1 1564w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic3.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Now that our application is truly reactive we can change out changeDetection to OnPush. <a href="https://angular.io/api/core/ChangeDetectionStrategy#members" target="_blank" rel="noreferrer noopener">More info on it here.</a></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="366" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?resize=640%2C366&#038;ssl=1" alt="" class="wp-image-222" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?resize=1024%2C586&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?resize=300%2C172&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?resize=768%2C440&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?resize=1536%2C879&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?w=1562&amp;ssl=1 1562w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic4.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Change template to using async pipe. <a href="https://angular.io/api/common/AsyncPipe" target="_blank" rel="noreferrer noopener" title="async pipe">Read about it here!</a></p>



<p>We can use data$ in all other components the same way as here:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="180" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic5.png?resize=640%2C180&#038;ssl=1" alt="" class="wp-image-223" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic5.png?resize=1024%2C288&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic5.png?resize=300%2C84&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic5.png?resize=768%2C216&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2021/02/pic5.png?w=1168&amp;ssl=1 1168w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<p>Checkout Stackblitz with code complete:</p>



<p><a href="https://stackblitz.com/github/katesky/messages-sent-app/tree/with-service" target="_blank" rel="noreferrer noopener" title="good code">https://stackblitz.com/github/katesky/messages-sent-app/tree/with-service</a></p>



<p>I hope this article was usefull for you. </p>



<p>I was able to show you something new and you will avoid some of the mistakes I made when I got started with Angular.</p>



<p>One of my passions is to be able to inspire mothers to get started in technology sector.  I am a programmer with over 20 years of experance in IT.</p>



<p>I am also a mother of 5 children. I hope one day my daughters will be inspired by my story to go into STEM.</p>



<p>Till next time!</p>



<p>Kate Sky.</p>
</body>The post <a href="https://www.katesky.com/2021/02/18/better-ways-to-share-data-between-components/">Better ways to share data between components.</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">218</post-id>	</item>
		<item>
		<title>Angular NGRX enabling DevTools at runtime</title>
		<link>https://www.katesky.com/2020/06/22/angular-ngrx-enabling-devtools-at-runtime/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=angular-ngrx-enabling-devtools-at-runtime</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Mon, 22 Jun 2020 20:51:26 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<category><![CDATA[devtool]]></category>
		<category><![CDATA[ngrx]]></category>
		<category><![CDATA[redux]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=169</guid>

					<description><![CDATA[<p>Angular NGRX enabling DevTools at runtime In this article, I will cover a problem that I was working on in one of my projects. With help from the NGRX team, I was able to solve it.  Shot-out to @brandontroberts , @tim_deschryver, @AlexOkrushko! <br /><a href="https://www.katesky.com/2020/06/22/angular-ngrx-enabling-devtools-at-runtime/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2020/06/22/angular-ngrx-enabling-devtools-at-runtime/">Angular NGRX enabling DevTools at runtime</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<h2 class="wp-block-heading">Angular NGRX enabling DevTools at runtime</h2>



<p>In this article, I will cover a problem that I was working on in one of my projects. With help from the NGRX team, I was able to solve it.  Shot-out to <a href="https://twitter.com/brandontroberts">@brandontroberts</a> , <a href="https://twitter.com/tim_deschryver">@tim_deschryver</a>, <a href="https://twitter.com/AlexOkrushko">@AlexOkrushko</a>!</p>



<p>I hope it helps you when using NGRX, and you can also add it as part of your development process. </p>



<h3 class="wp-block-heading">Problem:</h3>



<p>I wanted to be able to enable DevTools at runtime. The reason I want to do that is to be able to let users report his/her application experience and especially the problems they are experiencing. </p>



<p>In other words, enable debugging reporting on the fly using NGRX framework.</p>



<h3 class="wp-block-heading">Solution:</h3>



<p>This article will be useful if you love Redux DevTools, but you don’t have them enabled in Production.</p>



<p>You would like to have your application to be able to switch to the reporting mode, even in Production.</p>



<p>I will cover the following steps:</p>



<ol class="wp-block-list"><li>Adding a lazy-loaded Feature Module</li><li>Dispatching an effect to create a StoreDevtoolsModule at runtime</li><li>Extras:<ol><li>Use hidden F1 key to enable a link for debugging. </li><li>Enable third party logging/debugging tools  </li></ol></li></ol>



<h3 class="wp-block-heading">Implementation:</h3>



<p>We start by adding a feature; we will call it ‘debug’.  </p>



<p>It will contain:</p>



<ol class="wp-block-list"><li> debug.action – We will use an NGRX action from this file to dispatch from the component.</li><li>debug.component. We will use Debug component to load our feature via a new route we will add to app.module. </li><li>debug.module – We will lazy-load this module that in the app.module, and it will contain a route to the component</li><li>app.module – Register a new feature with a lazy-loaded route</li><li>dev-tools.module – Module that will inject the StoreDevTools to kick-of the Redux tools registration from this module.</li><li>debug.effect – We will use this NGRX effect to catch an action dispatched. This effect will be responsible for the runt-time enabling of the dev tools.</li><li>root-store.module – Register new Effect in RootModule</li><li>app.componet – Add a hiddent button that can be turned visible by F1- hot key</li></ol>



<h4 class="wp-block-heading">debug.action.ts</h4>



<p>Add a new action to be dispatch to the store about the state change. </p>



<p>We prefix the type of the action with the name of the page that will dispatch this action. </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [3]; title: ; notranslate">
import { createAction } from '@ngrx/store';

export const enableDebug = createAction('[Debug Page] enable');
</pre></div>


<h4 class="wp-block-heading">debug.component.ts</h4>



<p>Add a new component. If you like, you can keep template and styles inline. Both are not used in this setup, so can easily be excluded. </p>



<p>I have an empty template because its not needed.</p>



<p>When component is loaded it will dispatch an action that will enable DevTools (line 14).  Effect is below, I promise!</p>



<p><strong>in terminal:</strong></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: powershell; title: ; notranslate">
ng generate component debug--inlineTemplate=true --inlineStyle=true
</pre></div>


<p><strong>in new file debug.component.ts</strong>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [14]; title: ; notranslate">
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { RootState } from '../+state/root.selectors';
import { enableDebug } from './debug.actions';

@Component({
  template: ``,
  selector: 'app-debug'
})
export class DebugComponent implements OnInit {
  constructor(private readonly store: Store&lt;RootState&gt;) {}

  ngOnInit(): void {
    this.store.dispatch(enableDebug());
  }
}

</pre></div>


<h4 class="wp-block-heading">debug.module.ts</h4>



<p>This module is lazy-loaded so it will be registering the child routes.</p>



<p><strong>debug.module.ts</strong>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [6]; title: ; notranslate">
import { NgModule } from '@angular/core';
import { DebugComponent } from './debug.component';
import { RouterModule } from '@angular/router';
@NgModule({
  imports: [ 
      RouterModule.forChild([{ path:'',component:DebugComponent}])
  ],
  declarations: [DebugComponent],
  exports: [DebugComponent]

})
export class DebugModule {
  constructor(){}
}

</pre></div>


<h4 class="wp-block-heading">app.module.ts</h4>



<p>This module we will add a new route and lazy-load it with a feature module. </p>



<p>This is a code-snipet , so if you want to see full code check out my repository.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [4,5,6]; title: ; notranslate">
{
    path: 'debug',
    loadChildren: () =&gt;
    import('./debug/debug.module').then(
      m =&gt; m.DebugModule
    )
      
  },
</pre></div>


<h4 class="wp-block-heading">dev-tools.module.ts</h4>



<p>This module will be compiled and created in the effect. </p>



<p>On line 14th you can refresh the tools. I didn’t see much of a difference in value having it execute.</p>



<p></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [13,16]; title: ; notranslate">
import { NgModule } from '@angular/core';
import { StoreDevtoolsModule, StoreDevtools } from '@ngrx/store-devtools';
@NgModule({
  imports: [
    StoreDevtoolsModule.instrument({
      maxAge: 25, // Retains last 25 states
      logOnly: true
    })
  ]
})
export class DevToolsModule {
  constructor(private storeDevtools: StoreDevtools) {
    // storeDevtools.refresh();
  }
} 

</pre></div>


<h4 class="wp-block-heading">debug.effect.ts</h4>



<p>Effect class is responsible for reacting to the action dispatched from the component.  It filters out actions that it is subscribing to and when enableDebug is dispatched, effect is using ‘exhaustMat’ operator to make sure that if same action is dispatched it will continue to execute. In other words dropping incoming request.</p>



<p>Next it uses injected compiler object to compile dev-tools.module and creates it on lines 21-24.</p>



<p>Once that is completed, we have devtools enabled and redux tools can be used to track our state changes.</p>



<p>We know that we will have a manual mechanism of turning debugging option on so we can redirect our user back to that location. In this case it’s root of the application or home. So the changeLink action is returned via this effect.</p>



<p></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [21,22,23,24]; title: ; notranslate">
import { Injectable, Compiler, Injector } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';

import * as DebugActions from './debug.actions';
import { exhaustMap } from 'rxjs/operators';
import { DevToolsModule } from './dev-tools-module'; 
import { changeLink } from '../+state/root.actions';

@Injectable()
export class DebugEffects {
  constructor(
    private actions$: Actions,
    private compiler: Compiler,
    private injector: Injector
  ) {}

  debugAction$ = createEffect(() =&gt;
    this.actions$.pipe(
      ofType(DebugActions.enableDebug),
      exhaustMap(async () =&gt; {
        const m = this.compiler.compileModuleSync&lt;DevToolsModule&gt;(
          DevToolsModule
        );
        m.create(this.injector); 
        return changeLink({ link: '' });
      })
    )
  );
}

</pre></div>


<p>If you checkout my repository you will see that I just imported DevToolsModule into the DebugModule for simplicity. I kept the effect for other use case in Extra#2.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [8]; title: ; notranslate">
import { NgModule } from '@angular/core';
import { DebugComponent } from './debug.component';
import { RouterModule } from '@angular/router';
import { DevToolsModule } from './dev-tools-module';
@NgModule({
  imports: [ 
      RouterModule.forChild([{ path:'',component:DebugComponent}]),
      DevToolsModule
  ],
  declarations: [DebugComponent],
  exports: [DebugComponent]

})
export class DebugModule {
  constructor(){}
  
}

</pre></div>


<h4 class="wp-block-heading">app.component.html</h4>



<p>Add anywhere you would like to include a hidden button. So next time your user is having some unexplainable issues they can hit F1 and it will become visible.</p>



<p>Can you tell I am using material components?  So if you this code make sure you import all necessary Modules for Material <a href="https://material.angular.io/components/button/api" target="_blank" rel="noreferrer noopener">here</a>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: xml; title: ; notranslate">
&lt;button *ngIf="isDebugVisible" (click)="onDebug()"mat-icon-button aria-label="debug"&gt;
  &lt;mat-icon&gt;bug_report&lt;/mat-icon&gt;
&lt;/button&gt;
</pre></div>


<h4 class="wp-block-heading">app.component.ts</h4>



<p>Extra #1: As promised I will give this little trick. I added hidden button to help user discover issues and be part of the debugging process.</p>



<p>We will add a function to make our button visible with HostListener, filtering out keys. </p>



<p>Next we will add a button click event that will redirect our user to the lazy-loaded module we just setup.  </p>



<p><strong>Remember</strong>: user will be redirected back here from the debug.effect? </p>



<p>So we can turn off the button – our devtools are enabled!</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
  onDebug() {
    this.store.dispatch(changeLink({ link: 'debug' }));
    this.isDebugVisible = false;
  }
  @HostListener('document:keydown', ['$event'])
  keypress(e: KeyboardEvent) {
    if (e.key === 'F1') {
      this.isDebugVisible = true;
    }
  }
</pre></div>


<h4 class="wp-block-heading">Extras #2</h4>



<p>If you haven’t heard of LogRocket yet. Let me Introduce you. <a href="http://www.logrocket.com">www.logrocket.com</a> This is a very cool product that you can plugin to the application to see a full path of your user experience with visual snap shots.</p>



<p>How cool is that?</p>



<p>If you follow their instruction it is pretty straight forward to include and get started with in your application.</p>



<p><strong> https://app.logrocket.com/&lt;replace-with-yourcode&gt;/settings/integrations/</strong></p>



<p>It is a paid product, if you exceed the number of requests that are free! </p>



<p>But let see if we can utilize a free version by only enabling the setup from our debug lazy-loaded module dev-tools.module? </p>



<p><strong>update debug.effect.ts</strong></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [7,26]; title: ; notranslate">
import { Injectable, Compiler, Injector } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';

import * as DebugActions from './debug.actions';
import { exhaustMap } from 'rxjs/operators';
import { DevToolsModule, LOGROCKET_INIT_KEY } from './dev-tools-module';
import * as LogRocket from 'logrocket'; 
import { changeLink } from '../+state/root.actions';

@Injectable()
export class DebugEffects {
  constructor(
    private actions$: Actions,
    private compiler: Compiler,
    private injector: Injector
  ) {}

  debugAction$ = createEffect(() =&gt;
    this.actions$.pipe(
      ofType(DebugActions.enableDebug),
      exhaustMap(async () =&gt; {
        const m = this.compiler.compileModuleSync&lt;DevToolsModule&gt;(
          DevToolsModule
        );
        m.create(this.injector);
        LogRocket.init(LOGROCKET_INIT_KEY);
        return changeLink({ link: '' });
      })
    )
  );
}

</pre></div>


<p><strong>update dev-tool.module.ts</strong></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; highlight: [3,4,5,6,7,8,9,10,11,12,13,14,15,16,24,25,26,27,28,29,30,31]; title: ; notranslate">
import { NgModule } from '@angular/core';
import { StoreDevtoolsModule, StoreDevtools } from '@ngrx/store-devtools';
import { USER_PROVIDED_META_REDUCERS } from '@ngrx/store';
import * as LogRocket from 'logrocket';
import createNgrxMiddleware from 'logrocket-ngrx';
import { MetaReducer, State } from '@ngrx/store'; 
import { RootState } from '../+state/root.selectors';
const logrocketMiddleware = createNgrxMiddleware(LogRocket, {});

export const metaReducers: MetaReducer&lt;any&gt;[] = [];

export function getMetaReducers(): MetaReducer&lt;RootState&gt;[] {
  return metaReducers.concat([logrocketMiddleware]);
}
export const LOGROCKET_INIT_KEY = '&lt;replace-with-your-code';

@NgModule({
  imports: [
    StoreDevtoolsModule.instrument({
      maxAge: 25, // Retains last 25 states
      logOnly: true
    })
  ],
  providers: [
  
    {
      provide: USER_PROVIDED_META_REDUCERS,
      useFactory: getMetaReducers
    }
  ]}
)
export class DevToolsModule {
  constructor(private storeDevtools: StoreDevtools) {
    // storeDevtools.refresh();
  }
}

</pre></div>


<p>Now that we have this setup, we can see our requests are only feeding into our LogRocket account after we enabled debug!</p>



<p></p>



<p>I hope you enjoyed this article! Tweet you questions or comments <a rel="noreferrer noopener" href="https://twitter.com/intent/tweet?text=Hi,@katesky8%20%22Question/comment%20about%20your%20post%20Angular%20NGRX%20enabling%20DevTools%20at%20runtime%20%F0%9F%91%8D%F0%9F%91%8D%F0%9F%91%8D&amp;url=https://www.katesky.com/2020/06/22/angular-ngrx-enabling-devtools-at-runtime" target="_blank">here</a>. </p>



<p>I will be glad to connect too!</p>



<p></p>



<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex">



<li class="wp-social-link wp-social-link-twitter  wp-block-social-link"><a href="https://twitter.com/intent/tweet?text=Hi,@katesky8%20Question/comment%20about%20your%20post%20Angular%20NGRX%20enabling%20DevTools%20at%20runtime%20%F0%9F%91%8D%F0%9F%91%8D%F0%9F%91%8D&amp;url=https://www.katesky.com/2020/06/22/angular-ngrx-enabling-devtools-at-runtime" class="wp-block-social-link-anchor"><svg width="24" height="24" viewbox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Twitter</span></a></li>







<li class="wp-social-link wp-social-link-twitter  wp-block-social-link"><a href="https://twitter.com/KateSky8" class="wp-block-social-link-anchor"><svg width="24" height="24" viewbox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Twitter</span></a></li></ul>



<p>If you would like to see a repository where I added this implementation,  follow this github link: </p>



<p><a href="https://github.com/katesky/saraphan-radio/tree/azure/apps/shell-app/src/app/debug">https://github.com/katesky/saraphan-radio/tree/azure/apps/shell-app/src/app/debug</a> </p>
</body>The post <a href="https://www.katesky.com/2020/06/22/angular-ngrx-enabling-devtools-at-runtime/">Angular NGRX enabling DevTools at runtime</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">169</post-id>	</item>
		<item>
		<title>Enterprise Application Journey</title>
		<link>https://www.katesky.com/2020/04/21/enterprise-application-journey/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enterprise-application-journey</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Tue, 21 Apr 2020 20:42:59 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Monorepo]]></category>
		<category><![CDATA[Enterprise Application]]></category>
		<category><![CDATA[full-stack]]></category>
		<category><![CDATA[kate sky]]></category>
		<category><![CDATA[ngrx]]></category>
		<category><![CDATA[state management]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=137</guid>

					<description><![CDATA[<p>Angular: front-end from start to MVP by Kate Sky I am making this post as the first step in documenting my journey of building an Enterprise application for my side project. The application is in the process of going towards an MVP. This <br /><a href="https://www.katesky.com/2020/04/21/enterprise-application-journey/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2020/04/21/enterprise-application-journey/">Enterprise Application Journey</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<h3 class="wp-block-heading">Angular: front-end from start to MVP</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>by Kate Sky</p></blockquote>



<p>I am making this post as the first step in documenting my journey of building an Enterprise application for my side project.</p>



<p>The application is in the process of going towards an MVP.</p>



<p>This application is an “Uber for home services.” </p>



<p>The reason I had started this project: is to provide a value-based service while practicing and teaching others skills I had acquired over the years.</p>



<p>The objective of this post is to establish a timeline of the application going live from its infancy.</p>



<hr class="wp-block-separator">



<p>Following is the list of topics that we are going to discuss in this article:</p>



<ol class="wp-block-list"><li>Application Stack</li><li>Architectural decisions<ol style="user-select: auto;"><li>Monorepo with Nx</li><li>Domain-Driven Design with Angular</li><li>State management with NGRX </li><li>Logging with LogRocket</li><li>Authentication with Auth0</li></ol></li><li>Conclusion</li><li>Links</li></ol>



<hr class="wp-block-separator">



<h4 class="wp-block-heading">1. Application Stack</h4>



<p>WEB- Angular<br>API – .Net Core<br>DB – SQL server</p>



<hr class="wp-block-separator">



<h4 class="wp-block-heading">2. Architectural decisions</h4>



<p>For web client, I am using Angular framework.</p>



<p>My goal – to be able to scale the development of this application by having the ability to go from one team to many teams building multiple frontend and backend applications all in the same workspace. </p>



<p>I chose <a target="_blank" href="https://nx.dev/angular" rel="noreferrer noopener">NX</a>, so developers have a holistic dev experience powered by an advanced CLI (with editor plugins), capabilities for controlled code sharing, and consistent code generation.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="446" height="664" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/1.png?resize=446%2C664&#038;ssl=1" alt="" class="wp-image-139" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/1.png?w=446&amp;ssl=1 446w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/1.png?resize=202%2C300&amp;ssl=1 202w" sizes="auto, (max-width: 446px) 100vw, 446px" /></figure></div>



<hr class="wp-block-separator">



<p>Monorepos allow huge enterprise applications to be subdivided into small and maintainable libraries. I followed the best practice from the creators of NX and have added a <a rel="noreferrer noopener" style="user-select: auto;" target="_blank" href="https://www.npmjs.com/package/@angular-architects/ddd">domain-driven</a> design approach to creating the features. One of the features is the search capability for the providers that are displayed. I added a domain ‘Providers’ it contains the feature store for state management and the infrastructure where service is implemented to call the API.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>We need to first define criteria for slicing our application into individual parts and we must establish rules for communication between them.</p><cite>referenced: <a href="https://www.angulararchitects.io/aktuelles/sustainable-angular-architectures-1/">https://www.angulararchitects.io/aktuelles/sustainable-angular-architectures-1/</a></cite></blockquote>



<p></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="463" height="379" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/2.png?resize=463%2C379&#038;ssl=1" alt="" class="wp-image-140" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/2.png?w=463&amp;ssl=1 463w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/2.png?resize=300%2C246&amp;ssl=1 300w" sizes="auto, (max-width: 463px) 100vw, 463px" /></figure></div>



<hr class="wp-block-separator">



<p>I have added <a rel="noreferrer noopener" style="user-select: auto;" target="_blank" href="https://ngrx.io/">NGRX </a>from the very beginning because I would like to have an ability to replay the user’s trip through the application, and I will be adding <a rel="noreferrer noopener" style="user-select: auto;" target="_blank" href="https://logrocket.com/">LogRocket </a>to view that path. NGRX will also help me write clean reactive components with async pipes. Root store has its own module and is at the root of the application. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Stop guessing why bugs happen. LogRocket lets you replay what users do on your site, helping you reproduce bugs and fix issues faster.</p><cite><a href="https://logrocket.com/">https://logrocket.com/</a></cite></blockquote>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="467" height="482" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/3-2.png?resize=467%2C482&#038;ssl=1" alt="" class="wp-image-143" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/3-2.png?w=467&amp;ssl=1 467w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/3-2.png?resize=291%2C300&amp;ssl=1 291w" sizes="auto, (max-width: 467px) 100vw, 467px" /></figure></div>



<hr class="wp-block-separator">



<p>Since we have 2 features now, we can see that NGRX stores for each feature are located near the domain for each feature’s library. There is separate module for each store to be able to import each feature module lazily.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="498" height="575" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/4.png?resize=498%2C575&#038;ssl=1" alt="" class="wp-image-144" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/4.png?w=498&amp;ssl=1 498w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/4.png?resize=260%2C300&amp;ssl=1 260w" sizes="auto, (max-width: 498px) 100vw, 498px" /></figure></div>



<hr class="wp-block-separator">



<p>Users have to register, and for authentication, I picked <a rel="noreferrer noopener" style="user-select: auto;" target="_blank" href="https://auth0.com/">Auth0</a>. Right now, you can see that authentication is on the root store. I have a login and logout actions that are calling the service to execute the correct code. I am using the service I download from the example provided by auth0. It still needs to be cleaned up. </p>



<p>I added a component for the callback path need for the login of the authentication. There is a CanActivate guard that is used for components that need an authorized user.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="506" height="454" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/5.png?resize=506%2C454&#038;ssl=1" alt="" class="wp-image-145" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/5.png?w=506&amp;ssl=1 506w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/04/5.png?resize=300%2C269&amp;ssl=1 300w" sizes="auto, (max-width: 506px) 100vw, 506px" /></figure></div>



<hr class="wp-block-separator">



<h4 class="wp-block-heading">3 . Conclusion</h4>



<p>In conclusion, we will go through whats next.</p>



<p>I wanted to get the frontend started first and have a clear user experience throughout the application.</p>



<p>I will add the .net Core API to store the data to the database next. </p>



<p>I deployed code to GitHub pages to be able to get user feedback at the very early stages of this application.</p>



<hr class="wp-block-separator">



<h4 class="wp-block-heading">4. Links</h4>



<p>Code: <a style="user-select: auto;" href="https://github.com/katesky/saraphan-radio">https://github.com/katesky/saraphan-radio</a></p>



<p>Dev version: <a href="https://katesky.github.io/saraphan-radio/">https://katesky.github.io/saraphan-radio/</a></p>



<p>Domain: <a href="http://sarafanradio.com/">http://saraphanradio.com</a></p>



<p></p>



<p></p>
</body>The post <a href="https://www.katesky.com/2020/04/21/enterprise-application-journey/">Enterprise Application Journey</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">137</post-id>	</item>
		<item>
		<title>Angular: NGRX clean architecture with multiple stores (Part 1.5)</title>
		<link>https://www.katesky.com/2020/02/03/angular-ngrx-clean-architecture-with-multiple-stores-part-1-5/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=angular-ngrx-clean-architecture-with-multiple-stores-part-1-5</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Mon, 03 Feb 2020 11:54:00 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<category><![CDATA[kate sky]]></category>
		<category><![CDATA[ngrx]]></category>
		<category><![CDATA[state managment]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=62</guid>

					<description><![CDATA[<p>Angular: NGRX clean architecture with multiple stores by Kate Sky Before we go into Part 2 (testing of the multi-feature/store), I want to demonstrate the implementation of lazy loading of modules with multiple stores. So the objective of this article will be <br /><a href="https://www.katesky.com/2020/02/03/angular-ngrx-clean-architecture-with-multiple-stores-part-1-5/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2020/02/03/angular-ngrx-clean-architecture-with-multiple-stores-part-1-5/">Angular: NGRX clean architecture with multiple stores (Part 1.5)</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<h3 class="has-secondary-color has-text-color wp-block-heading"> Angular: NGRX clean architecture with multiple stores</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>by Kate Sky</p></blockquote>



<p>Before we go into Part 2 (testing of the multi-feature/store), I want to demonstrate the implementation of lazy loading of modules with multiple stores. So the objective of this article will be to show you how to add feature stores to the Feature module, which are loaded lazily when a route is activated.</p>



<p>Finally, I am going to provide links to the repository to GitHub.</p>



<p>Following is the list of topics that we are going to discuss in this article:</p>



<ol class="wp-block-list"><li>Application objective.</li><li>Application architecture</li><li>Lazy loading of the feature modules</li><li>Lazy loading demo</li><li>Conclusion</li><li>Links</li><li>Part 2 ( to be continued)</li></ol>



<h4 class="wp-block-heading">1. The objective of the application     </h4>



<p>In this example, I want to demonstrate an app that will track home buying data. It will have a dashboard with links to a favorite list and a list of visited homes. Users will also be able to click on a link that will take her to a list of all prospective homes. From there, she can go into detail for each home.  </p>



<h4 class="wp-block-heading">2. Application architecture and folder structure</h4>



<p>In this example, we have separated this application in high-level feature modules. By doing so, it allows us to lazy load features along with store modules based on the current route.  </p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="640" height="362" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?resize=640%2C362&#038;ssl=1" alt="" class="wp-image-65" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?resize=1024%2C579&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?resize=300%2C170&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?resize=768%2C434&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?resize=1536%2C869&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?w=1561&amp;ssl=1 1561w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/1.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption> AppModule only has RootStoreModule imported. <br><a href="https://github.com/katesky/ngrx-multy-store-part-1.5/blob/master/src/app/app.module.ts">app.module.ts</a></figcaption></figure></div>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="348" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?resize=640%2C348&#038;ssl=1" alt="" class="wp-image-66" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?resize=1024%2C557&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?resize=300%2C163&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?resize=768%2C417&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?resize=1536%2C835&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?resize=1568%2C852&amp;ssl=1 1568w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?w=1630&amp;ssl=1 1630w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/2.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption> And Store1Module is registered in the Feature module <br><a href="https://github.com/katesky/ngrx-multy-store-part-1.5/blob/master/src/app/feature1/home-list.module.ts">home-list.module.ts</a></figcaption></figure>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="601" height="618" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/3.png?resize=601%2C618&#038;ssl=1" alt="" class="wp-image-67" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/3.png?w=601&amp;ssl=1 601w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/3.png?resize=292%2C300&amp;ssl=1 292w" sizes="auto, (max-width: 601px) 100vw, 601px" /><figcaption>Notice the folder structure of the application. We moved Store1Module in the same folder as a feature module with a routing module for that feature</figcaption></figure></div>



<h4 class="wp-block-heading">3. Lazy loading of the feature modules</h4>



<p> “By default, NgModules are eagerly loaded, which means that as soon as the app loads, so do all the NgModules, whether or not they are immediately necessary. For large apps with lots of routes, consider lazy loading—a design pattern that loads NgModules as needed. Lazy loading helps keep initial bundle sizes smaller, which in turn helps decrease load times. ” – From <a href="https://angular.io/guide/lazy-loading-ngmodules">Angule.io</a></p>



<p>We now can lazy load our feature module by registering it in the routing module:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="297" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?resize=640%2C297&#038;ssl=1" alt="" class="wp-image-68" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?resize=1024%2C475&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?resize=300%2C139&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?resize=768%2C356&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?resize=1536%2C712&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?resize=1568%2C727&amp;ssl=1 1568w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?w=1684&amp;ssl=1 1684w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/4.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption><a href="https://github.com/katesky/ngrx-multy-store-part-1.5/blob/master/src/app/app-routing.module.ts">app-routing.module.ts</a></figcaption></figure>



<h4 class="wp-block-heading">4. Lazy loading demo</h4>



<p>When we have a clean separation of the features into modules, it allows us to register routes to be lazy-loaded.<br>
Let’s see it in action by checking the console:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="640" height="295" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?resize=640%2C295&#038;ssl=1" alt="" class="wp-image-69" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?resize=1024%2C472&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?resize=300%2C138&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?resize=768%2C354&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?resize=1536%2C709&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?resize=1568%2C723&amp;ssl=1 1568w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?w=1797&amp;ssl=1 1797w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/5.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure></div>



<p>When app navigates to <code>Homes</code> we see that our feature1 module is fetched and an additional file appears in the console:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="323" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?resize=640%2C323&#038;ssl=1" alt="" class="wp-image-70" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?resize=1024%2C517&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?resize=300%2C151&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?resize=768%2C388&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?resize=1536%2C775&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?resize=1568%2C791&amp;ssl=1 1568w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?w=1722&amp;ssl=1 1722w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/02/6.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<h4 class="wp-block-heading">5. Conclusion</h4>



<p>In this article, I tried to deliver a technical guide on how to organize your application NGRX stores and provide you with examples of how they can be registered alongside with routing modules.</p>



<p>We started with an application description. I went over the architecture and folder structure. We then looked at registering a lazy loaded module. Finally, we looked at the demo.</p>



<h4 class="wp-block-heading">6. Links</h4>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" target="_blank" href="https://github.com/katesky/ngrx-multy-store-part-1.5">https://github.com/katesky/ngrx-multy-store-part-1.5</a></li><li><a rel="noreferrer noopener" target="_blank" href="https://stackblitz.com/edit/ngrx-multy-store-part-15">https://stackblitz.com/edit/ngrx-multy-store-part-15</a></li></ul>



<h4 class="wp-block-heading">7. Part 2 (To be continued…)</h4>



<p>Where I will show how to test a component that uses a feature store. Some mocking will take place.</p>



<p>I hope this article helps you out with adding NGRX to your application.</p>



<hr class="wp-block-separator">



<p></p>
</body>The post <a href="https://www.katesky.com/2020/02/03/angular-ngrx-clean-architecture-with-multiple-stores-part-1-5/">Angular: NGRX clean architecture with multiple stores (Part 1.5)</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">62</post-id>	</item>
		<item>
		<title>Angular: NGRX clean architecture with multiple stores (Part 1)</title>
		<link>https://www.katesky.com/2020/01/17/angular-ngrx-multiple-store-architecture-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=angular-ngrx-multiple-store-architecture-part-1</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Fri, 17 Jan 2020 22:57:23 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<category><![CDATA[kate sky]]></category>
		<category><![CDATA[ngrx]]></category>
		<category><![CDATA[state managment]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=53</guid>

					<description><![CDATA[<p>Angular: NGRX clean architecture with multiple stores by Kate Sky The objective of this article is to provide a technical implementation of the NGRX for an application with a complexity that could benefit from adding feature store(s) in addition to the root <br /><a href="https://www.katesky.com/2020/01/17/angular-ngrx-multiple-store-architecture-part-1/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2020/01/17/angular-ngrx-multiple-store-architecture-part-1/">Angular: NGRX clean architecture with multiple stores (Part 1)</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<h3 class="has-secondary-color has-text-color wp-block-heading">Angular: NGRX clean architecture with multiple stores</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>by Kate Sky</p></blockquote>



<p>The objective of this article is to provide a technical implementation of the <a href="https://github.com/ngrx/platform">NGRX</a> for an application with a complexity that could benefit from adding feature store(s) in addition to the root store.</p>



<p>Finally, I am going to provide links to my GitHub repository with the example code. </p>



<p>In part 2, I will show how to unit test components that use a feature store and later we will go into the unit testing of the NGRX store itself.</p>



<p>This is the list of topics that we are going to discuss in
this article:</p>



<ol class="wp-block-list"><li>A high-level use case for state management.</li><li>Getting started with a root store</li><li>Adding feature store to the application</li><li>Organizing your store folders</li><li>Adding stores to your components</li><li>Conclusion</li><li>Links</li><li>Part 2 ( to be continued)</li></ol>



<h4 class="wp-block-heading">1. High-level use case for state management.</h4>



<p>When a decision has been made to manage the state of your complex application by adding NGRX, it is important to understand that you will not be able to convert the whole application to use the store right from the start.</p>



<p>It will be a gradual process that I will try to provide a technical guide for. In the example, you will see a RootStoreModule and a Store1Module.</p>



<p>The root store is where you will start. This store will be the highest level of user/system actions that can be performed in the application. For example, a dashboard app will have links to other areas, so the root store will load the available links and user access and privileges needed for the app to run. Root store will manage the state of the highest level of the application or lowest since it is a root (pun attended).</p>



<p>The feature store is an abstraction for parts of the application that are feature-based. For example, the user will click on a feature of the application from a dashboard, that allows him to manage orders, sales, employees, etc.  This is where the feature will load or change data using the feature store. It will manage the state of this feature along. </p>



<p>First, you must install NGRX by following the installation steps from <a href="https://ngrx.io/guide/store/install">https://ngrx.io/guide/store/install</a></p>



<h4 class="wp-block-heading">2. Getting started with a root store</h4>



<p>Second, you will create a folder where you will hold all files related to the root store. </p>



<p>Inside the folder, you will have files needed for the store: actions, effects, reducers and an index file for exports. One of the necessary imports is CommonModule and reducers and effects. </p>



<p>If you use the CLI’s “ng add @ngrx/store” the structure is flatter. I like to organize it in a more 2D way.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="371" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/1.png?resize=640%2C371&#038;ssl=1" alt="" class="wp-image-54" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/1.png?w=957&amp;ssl=1 957w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/1.png?resize=300%2C174&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/1.png?resize=768%2C445&amp;ssl=1 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption>root-store.module.ts</figcaption></figure>



<p>Second, you will add the RootStoreModule to the app.module( CLI will add it for you!)</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="413" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/2.png?resize=640%2C413&#038;ssl=1" alt="" class="wp-image-55" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/2.png?resize=1024%2C660&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/2.png?resize=300%2C193&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/2.png?resize=768%2C495&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/2.png?w=1074&amp;ssl=1 1074w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption>app.module.ts</figcaption></figure>



<h4 class="wp-block-heading">3. Adding Feature store to the application</h4>



<p>When adding a feature store module and adding the imports one major difference from the root is the <code>forFeature</code> method. </p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="378" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/3.png?resize=640%2C378&#038;ssl=1" alt="" class="wp-image-56" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/3.png?resize=1024%2C604&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/3.png?resize=300%2C177&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/3.png?resize=768%2C453&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/3.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption>feature store in store1.module.ts</figcaption></figure>



<p>Ones all the files are created you can add feature module to the app.module just like the RootStoreModule</p>



<h4 class="wp-block-heading">4. Organizing your store folders</h4>



<p>In this simple example, you can see a separate folder for the feature store on the same level as the root store, but in a real application, I recommend adding a feature store folder on the same level as the feature folder. </p>



<h4 class="wp-block-heading">5. Adding stores to your components</h4>



<p>Since this example uses both stores in the app component, it’s pretty clear how easy it is to use the store and create a truly reactive application using an NGRX store.</p>



<p>In AppComponent you can find root store and feature store usage.</p>



<p>Stores are injected into the constructor and actions are
dispatched to load the data:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="370" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/4.png?resize=640%2C370&#038;ssl=1" alt="" class="wp-image-57" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/4.png?resize=1024%2C592&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/4.png?resize=300%2C174&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/4.png?resize=768%2C444&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/4.png?w=1198&amp;ssl=1 1198w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption>app.component.ts</figcaption></figure>



<p>You can see that the template is using the async pipe to load the data, there are no subscribe events. Observables are assigned the selectors from the store:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="640" height="295" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?resize=640%2C295&#038;ssl=1" alt="" class="wp-image-58" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?resize=1024%2C472&amp;ssl=1 1024w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?resize=300%2C138&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?resize=768%2C354&amp;ssl=1 768w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?resize=1536%2C708&amp;ssl=1 1536w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?resize=1568%2C723&amp;ssl=1 1568w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?w=1867&amp;ssl=1 1867w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2020/01/5.png?w=1280&amp;ssl=1 1280w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>



<h4 class="wp-block-heading">6. Conclusion</h4>



<p>In this article, I tried to deliver a technical guide on how to organize your application NGRX stores and provide you with examples of how they can be organized.</p>



<p>We started by setting up the root and feature stores and registering them in the app module. We then added the stores to a component and saw how data is displayed on the screen.</p>



<h4 class="wp-block-heading">7. Links</h4>



<ul class="wp-block-list"><li><a href="https://github.com/katesky/ngrx-multy-store">https://github.com/katesky/ngrx-multy-store</a></li><li><a href="https://stackblitz.com/edit/github-ngrx-multy-store">https://stackblitz.com/edit/github-ngrx-multy-store</a></li><li><a href="https://github-ngrx-multy-store.stackblitz.io">https://github-ngrx-multy-store.stackblitz.io</a></li></ul>



<h4 class="wp-block-heading">8. Part 2 (To be continued…) </h4>



<p>Where I will show how to test a component that uses a feature
store. Some mocking will take place.</p>



<p>I kept this project as simple as possible, so you can even
take the source code and add it to your application as a template. I know I will
in the future.</p>



<p>I hope this article helps you out with adding NGRX to your application.</p>
</body>The post <a href="https://www.katesky.com/2020/01/17/angular-ngrx-multiple-store-architecture-part-1/">Angular: NGRX clean architecture with multiple stores (Part 1)</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">53</post-id>	</item>
		<item>
		<title>Angular state management with NgRx</title>
		<link>https://www.katesky.com/2019/09/03/angular-state-management-with-ngrx/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=angular-state-management-with-ngrx</link>
		
		<dc:creator><![CDATA[Katerina Gable]]></dc:creator>
		<pubDate>Tue, 03 Sep 2019 00:50:58 +0000</pubDate>
				<category><![CDATA[angular]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[ngrx]]></category>
		<guid isPermaLink="false">https://www.katesky.com/?p=7</guid>

					<description><![CDATA[<p>Using custom selectors for one-to-one or one-to-many data relationships. by Kate Sky When implementing state management with Ngrx we often have a predefined API that can not be changed. I ran across a business case: back end API is written in a <br /><a href="https://www.katesky.com/2019/09/03/angular-state-management-with-ngrx/" class="more-link">Read More</a></p>
The post <a href="https://www.katesky.com/2019/09/03/angular-state-management-with-ngrx/">Angular state management with NgRx</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></description>
										<content:encoded><![CDATA[<body>
<h3 class="has-secondary-color has-text-color wp-block-heading">Using custom selectors for one-to-one or one-to-many data relationships.</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>by Kate Sky</p></blockquote>



<figure class="wp-block-gallery columns-1 is-cropped alignwide wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img data-recalc-dims="1" decoding="async" width="640" height="343" src="https://i0.wp.com/www.katesky.com/wp-content/uploads/2019/09/ngrx-redux-pattern-diagram-1.png?resize=640%2C343&#038;ssl=1" alt="" data-id="44" data-link="https://www.katesky.com/2019/09/03/angular-state-management-with-ngrx/ngrx-redux-pattern-diagram-1/" class="wp-image-44" loading="lazy" srcset="https://i0.wp.com/www.katesky.com/wp-content/uploads/2019/09/ngrx-redux-pattern-diagram-1.png?w=919&amp;ssl=1 919w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2019/09/ngrx-redux-pattern-diagram-1.png?resize=300%2C161&amp;ssl=1 300w, https://i0.wp.com/www.katesky.com/wp-content/uploads/2019/09/ngrx-redux-pattern-diagram-1.png?resize=768%2C411&amp;ssl=1 768w" sizes="auto, (max-width: 640px) 100vw, 640px" /><figcaption class="blocks-gallery-item__caption">Taken from  <a style="user-select: auto;" href="https://angularfirebase.com/lessons/angular-ngrx-redux-starter-guide/">https://angularfirebase.com </a></figcaption></figure></li></ul></figure>



<p class="has-text-align-left">When implementing state management with Ngrx we often have a predefined API that can not be changed. I ran across a business case: back end API is written in a way where  2 sets of data that are returned are depend on the other. One-to-one or one-to-many  relationship.  In order to map entities with corresponding ids we have to create a custom selector. </p>



<p>To make a selector that will do a lookup of another selector just add 4 Actions, 2 Effects and 3 selectors:</p>



<p>This is a declaration of the 2 Actions</p>



<pre class="wp-block-code"><code>export class LoadStudents implements Action{
  readonly type = ActionTypes.LoadStudents;
}
export class LoadTeachers implements Action{
  readonly type = ActionTypes.LoadTeachers;
}
export class Students implements Action{
  readonly type = ActionTypes.Students ;
  constructor(public payload: any){}
}
export class Teachers implements Action{
  readonly type = ActionTypes.Teachers;
  constructor(public payload: any){}
}
export type ActionUnion = LoadStudents| LoadTeachers
| Students  | Teachers  ;</code></pre>



<p>This is an implementation of the 2 effects</p>



<pre class="wp-block-code"><code>@Injectable()
export class Effects {

  constructor(private actions$: Actions, private service: myService ) { 
    }

    @Effect()
    loadStudents$ = this.actions$.pipe(
        ofType&lt;appActions.LoadStudents&gt;(appActions.ActionTypes.LoadStudents),
         switchMap(() =&gt; this.service.getStudents().pipe(
          map((data) =&gt;         
             new appActions.Students(data)
         ))));
    

    @Effect()
    loadTeachers$ = this.actions$.pipe(
        ofType&lt;appActions.LoadTeachers &gt;(appActions.ActionTypes.LoadTeachers ),
       switchMap(() =&gt; this.service.getTeachers().pipe(
          map((data) =&gt;         
             new appActions.Teachers(data)
         ))));
    
}</code></pre>



<p>When declaring selectors you have to remember that order of loaded data is not predictable and we have to account for it not all being loaded yet:</p>



<pre class="wp-block-code"><code>export interface State {
    csaApp: fromFeatures.State
}
export const reducers:ActionReducerMap&lt;State&gt;= {
    csaApp: fromFeatures.filteredAppReducer

}
const getAppState = createFeatureSelector&lt;fromFeatures.State&gt;('csaApp');
export const getStudents = createSelector(getAppState, (state)=&gt;state.students);
export const getTeachers= createSelector(getAppState, (state)=&gt;state.teachers);
export const getStudentsWithTeachers = createSelector(getStudents, getTeachers,(students, teachers) =&gt; {
    if(students === null || teachers === null) return null;
    students.map(s=&gt;s.teacher = teachers.find(t=&gt;t.id ===s.teacherId));
    return students;
}) </code></pre>



<p>Statement management using Ngrx is a huge subject and creating custom selector will be a great addition to any angular project.</p>



<p></p>



<p>See my github repository for a work-in-progress project I am workig on to support elementary school events for my children’s’ school.  <a style="user-select: auto;" href="https://github.com/katesky/csa-school-app">https://github.com/katesky/csa-school-app</a> </p>



<p>To see the working (wip) site visit:  <a style="user-select: auto;" href="https://katesky.github.io/csa-school-app/">https://katesky.github.io/csa-school-app</a></p>
</body>The post <a href="https://www.katesky.com/2019/09/03/angular-state-management-with-ngrx/">Angular state management with NgRx</a> first appeared on <a href="https://www.katesky.com">Kate Gable</a>.]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7</post-id>	</item>
	</channel>
</rss>
