# @StoreChunk

### Introduction

To benefit from `@ngrx-ducks'` dynamic facades, the respective class needs to be connected to NgRx [Store](https://ngrx.io/api/store/Store). To do so, `@ngrx-ducks/core` provides the decorator [storefacade](https://co-it.gitbook.io/ngrx-ducks/ngrx-ducks-core/architecture/storefacade "mention") that solves two tasks for you:

1. Connecting ducks and selectors with the store.
2. Registering the Facade as service in Angular's IoC container.

{% tabs %}
{% tab title="chunk.ts" %}

```typescript
import { StoreChunk } from '@ngrx-ducks/core';

@StoreChunk()
export class Chunk {}
```

{% endtab %}

{% tab title="component.ts" %}

```typescript
import { Component } from '@angular/core';
import { SomeFacade } from './some.facade';

@Component({/* ... */})
export class SomeComponent {
  constructor(private someFacade: SomeFacade) {}
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
If you use [storefacade](https://co-it.gitbook.io/ngrx-ducks/ngrx-ducks-core/architecture/storefacade "mention") you are not allowed to add a constructor taking any parameters. This is by design to keep the Chunk-Class side-effect-free.
{% endhint %}

{% hint style="info" %}
Using the Chunk-Service in you component also means that Redux-Infrastructure does not bleed into you components anymore.

The component only speaks to a service providing streams and dispatching messages (aka. actions).
{% endhint %}

### Automatic Store registration

#### TLDR

{% hint style="success" %}
See Store registration in action at ⚡️[StackBlitz](https://stackblitz.com/edit/ngrx-ducks-12-9ztnzp?file=src/app/counter/store/counter/counter.facade.ts).
{% endhint %}

#### **What is it?**&#x20;

Since NgRx Ducks version 12.4 a Chunk can be automatically be registered in the NgRx Store.

{% hint style="info" %}
The chapters [createDuck](https://co-it.gitbook.io/ngrx-ducks/ngrx-ducks-core/architecture/createduck), [createMutableDuck](https://co-it.gitbook.io/ngrx-ducks/ngrx-ducks-core/architecture/createmutableduck), [getReducer](https://co-it.gitbook.io/ngrx-ducks/ngrx-ducks-core/architecture/getreducers) and [getMutableReducer](https://co-it.gitbook.io/ngrx-ducks/ngrx-ducks-core/architecture/getmutablereducer) will teach you that a reducer function is generated out of the Facade class.

This Reducer function needs to be registered in the Store by using [StoreModule.forRoot](https://ngrx.io/guide/store/reducers#registering-root-state) or [StoreModule.forFeature](https://ngrx.io/guide/store/reducers#register-feature-state).
{% endhint %}

```typescript
@StoreChunk({
  feature: 'counter',
  defaults: { count: 0 }
})
export class Chunk {
```

Since Version **13** setting `feature` will cause NgRx Ducks to prefix every Action-Type for you.

For example, the feature-key `counter` is converted to the prefix `[Counter]` . You do not need to specify the Prefix manually any more :rocket:.

### **Plain Reducer Registration**

A feature can have one single reducer.

**@StoreFacade** accepts a configuration that specifies where the Facade's reducer is about to be registered in the Store.

{% tabs %}
{% tab title="chunk.ts" %}

```typescript
import { StoreChunk } from '@ngrx-ducks/core';

  /* Example
   * add = createDuck('[Counter] Add', (state: Counter, payload: number) => {
   *   return {
   *     ...state,
   *     count = state.count + payload
   *  }
   * });
  /*
}
```

{% endtab %}
{% endtabs %}

The configuration requires a key, where the reducer should be registered in the store. For that, you need to set `feature`.  The property `defaults` (aka. Initial State) specifies the start value of the reducer.

The configuration shown above causes the state to have a feature `counter` with an initial `count` of 0.

```javascript
{                 // state
  counter: {      // feature 
    count: 0      // defaults
  }
}
```

{% hint style="warning" %}
**@StoreFacade** produces a **Tree-Shakable-Provider.** That's why you need to inject the Facade somewhere to cause the State being initialised. If the Facade is not used anywhere in your project, the coresponding state is not available either.
{% endhint %}

{% hint style="info" %}
Using **@StoreFacade's** configuration also means that you do not need to use `StoreModule.forFeature()`. Setting up the feature and the reducer is done for you, automatically. 🚀
{% endhint %}

### Slice Registration

A feature can also have multiple reducers.

In NgRx you would need to set up an [ActionReducerMap\<T>](https://ngrx.io/api/store/ActionReducerMap) to combine multiple reducers that belong to a feature.\
NgRx Ducks allows you to write a single line of code to configure that the reducer is a sibling next to other reducers of the feature.

{% tabs %}
{% tab title="chunk.ts" %}

```typescript
export interface CounterFeatureState {
  simple: CounterState,
  complex: ConterComplexState
}

@StoreChunk<CounterFeatureState>({
  feature: 'counter',
  slice: 'simple',
  defaults 
})
```

{% endtab %}
{% endtabs %}

The configuration shown above causes the state to have a feature `counter` that contains a `slice` called *simple* with an initial `count` of 0.

```javascript
{                 // state
  counter: {      // feature 
    simple: {     // slice   
      count: 0    // defaults
    }
  }
}
```

### Type safety

`@StoreFacade` can be typed as well to ensure that `defaults` are set up the correct way.&#x20;

If you register a plain reducer for a `feature`, the type argument is responsible for checking the `defaults`.

{% tabs %}
{% tab title="chunk.ts" %}

```typescript
const defaults: CounterState = { count: 0, isLoading: true };

@StoreChunk<CounterState>({ feature: 'counter', defaults })
export class CounterFacade {}
```

{% endtab %}
{% endtabs %}

If you register a `slice` for a `feature`. The type argument will check if the key of the `slice` and the `defaults` are correct.

{% tabs %}
{% tab title="chunk.ts" %}

```typescript
export interface CounterFeatureState {
  simple: CounterState,
  complex: ConterComplexState
}

@StoreChunk<CounterFeatureState>({
  feature: 'counter',
  slice: 'simple',
  defaults 
})
```

{% endtab %}
{% endtabs %}

The following screenshot demonstrates the occurring compiler error if a slice-key is misspelled.

![Wrong slice key causes type error.](https://2125691487-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-tGttRMiwQ-1WWz8fU%2F-Mg6CqTl_zVuYwHjlwup%2F-Mg6In21EHAwcaqYru5Q%2FCleanShot%202021-08-02%20at%2016.37.45%402x.png?alt=media\&token=9a01025f-7dd1-4c97-8a45-258b04f4f3cb)
