# Quick Start

## Show me the code

You find a demo using `ngrx-ducks` at [ngrx-ducks-12](https://stackblitz.com/edit/ngrx-ducks-12). More explanations in another format here [Api Discussion](https://youtu.be/NSNsxSFJM-8?t=2177)

## Start with Ducks

{% hint style="info" %}
Follow this document up along with this demo [ngrx-ducks-12](https://stackblitz.com/edit/ngrx-ducks-12). There you will find the entire code that is shown in this article.💎
{% endhint %}

### Implement State Mutations

First create a file where the mutation logic for a certain state slice should live. Put selectors logic here as well.

Add a class that implements the needed `Case Reducers`, builds required selectors and triggers actions.

`createDuck` supports to create both triggering actions (for Effects) and mutating actions. Second parameter of `createDuck` is a `Case Reducer`. It has a similar style of creating a reducer which actually makes state mutations.

{% tabs %}
{% tab title="counter.facade.ts" %}
```typescript
import { createDuck } from '@ngrx-ducks/core';

@StoreFacade()
export class CounterFacade {
  counter = bindSelectors({ count: selectors.currentCount });
  
  loadCount = createDuck('[Counter] Set initial value',
    (state: CounterState, payload: number) => {
      return { ...state, count: payload };
  });
}
```
{% endtab %}
{% endtabs %}

The decorator `StoreFacade` introduces a new mechanism how the Facade is connected with the Store.🚀

### Create Reducer automatically

If you use Ducks there is no need to maintain switch-case statements. Now you can create the Reducer based on the Ducks you have created inside the Facade class.

{% tabs %}
{% tab title="counter.facade.ts" %}
```typescript
import { createDuck, getReducer, StoreFacade } from '@ngrx-ducks/core';

@StoreFacade()
export class CounterFacade {
  duck1 = createDuck('Duck 1', /* reducer function */);
  duck2 = createDuck('Duck 2', /* reducer function */);
  duck3 = createDuck('Duck 3', /* reducer function */);
}

// declare initial state and export counterReducer
const initialState = { count: 0 };
export const counterReducer = getReducer(initialState, CounterFacade);
```
{% endtab %}
{% endtabs %}

Just created `counterReducer` is a variable which can be used in ngrx method `combineReducers` [doc](https://ngrx.io/api/store/combineReducers). From that point our implementation of a reducer is finished. Example below shows us basic implementation.

{% tabs %}
{% tab title="index.ts" %}
```typescript
import { Action, combineReducers, MetaReducer } from '@ngrx/store';
import { CounterState, counterReducer } from './counter';

export interface State {
  simple: CounterState;
}

export function reducers(state: State, action: Action) {
  return combineReducers<State>({
    simple: counterReducer
  })(state, action);
}

export const metaReducers: MetaReducer<State>[] = [];
```
{% endtab %}
{% endtabs %}

### Inject the StoreFacade Service

To use your Facade you need to inject it into your component.

{% tabs %}
{% tab title="counter.component.ts" %}
```typescript
@Component({/* ... */})
export class CounterComponent {
  constructor(private counter: CounterFacade) {}
}
```
{% endtab %}
{% endtabs %}

Since the whole logic is implemented in a Facade (`CounterFacade` in our case) we only need to import that Facade.

{% hint style="info" %}
🎉 The API allows you to create dynamic facades and your components do not even know that Redux is working behind the scenes. We only rely on the contracts that we use messaging and streams.
{% endhint %}

{% hint style="info" %}
👓Thanks to TypeScript each method is strictly typed and the whole process of creating or dispatching Actions is transparent.
{% endhint %}

{% tabs %}
{% tab title="counter.component.ts" %}
```typescript
@Component({/* ... */})
export class CounterComponent implements OnInit {
  /* ... */

  ngOnInit() {
    this.counter.loadCount.dispatch(5000);
    //               ^ only type number is allowed 🎉
    //               - dispatches action: type: '[Counter] Set initial value'
    //                                    payload: 5000
  }
}
```
{% endtab %}
{% endtabs %}

### Use NgRx's selectors

Creating selectors is the same way as it's in NgRx.

{% tabs %}
{% tab title="counter.facade.ts" %}
```
import { bindSelectors, StoreFacade } from '@ngrx-ducks/core';

import * as selectors from './counter.selectors';

@StoreFacade()
export class CounterFacade {
  select = bindSelectors(selectors);
}
```
{% endtab %}

{% tab title="counter.selectors.ts" %}
```typescript
import 

// counter.component.ts
import { currentCount } from './counter.selectors';

export class CounterComponent {
  counter$: Observable<number>;

  constructor(private counter: CounterFacade) {
    this.count$ = this.counter.select.currentCount;
  }
}
```
{% endtab %}

{% tab title="counter.selectors.ts" %}
```typescript
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { State } from '..';

const visitCounter = createFeatureSelector<State>('counter');

export const currentCount = createSelector(
  visitCounter,
  counter => counter.simple.count
);
```
{% endtab %}
{% endtabs %}

### What if I don't want to dispatch the action directly?

No worries, `ngrx-ducks` gets you covered in this question. Each dispatching method provides an Action Creator.

{% tabs %}
{% tab title="component.ts" %}
```typescript
  ngOnInit() {
    // Yields Action
    this.counter.loadCount(5000);
    // {
    //   type: '[Counter] Set initial value',
    //   payload: 5000
    // }

    // Dispatches an action
    this.counter.loadCount.dispatch(5000);

  }
```
{% endtab %}
{% endtabs %}

You see `.loadCount(5000);` is a method as well. 🤯 This addition is very useful if you need to produce actions being returned by an Effect.

### Effects

You may wonder if `@ngrx-ducks` can help you with actions being dispatched to an Effect. Short answer: **Yes, it can**.

#### Setup

Let's use `createDuck` again! `createDuck` is the only entry point you need to know to create and dispatch actions. It works with calling Effects as well. It works with Effects just like actions work with Effects in ngrx.

{% tabs %}
{% tab title="counter.facade.ts" %}
```typescript
import { createDuck } from '@ngrx-ducks/core';

@StoreFacade()
export class CounterFacade {

  readonly loadCount = createDuck('[Counter] Load Count', dispatch<number>());

  // another action (called in Effect below)
  override = createDuck('[Counter] Set value',
    (state: CounterState, payload: number) => {
      return { ...state, count: payload };
    }
  );
}

export const counterActions = getActions(CounterFacade);
```
{% endtab %}
{% endtabs %}

#### Triggering an Effect

{% tabs %}
{% tab title="counter.component.ts" %}
```typescript
import { currentCount } from './counter.selectors';

@Component({
  /* ... */
})
export class CounterComponent {
  counter$: Observable<number>;

  constructor(private counter: CounterFacade) {
    // let's dispatch an action which is handled by an Effect
    this.counter.loadCount.dispatch(10);
  }
}
```
{% endtab %}
{% endtabs %}

#### Inside Effects

The last question is how an Effect itself handles actions with `ngrx-ducks`. An Effect filters the action type first. Let NgRx do it!😁

{% tabs %}
{% tab title="counter.effects.ts" %}
```typescript
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { counterActions } from './counter.facade';

@Injectable()
export class CounterEffects {
  setCounter = createEffect(() => this.actions$.pipe(
    ofType(counterActions.loadCount),
    delay(2000),
    map(({ payload }) => counterActions.override(payload))
  ));

  constructor(private actions$: Actions) {}
}
```
{% endtab %}
{% endtabs %}

As mentioned before, you can make use of the generated, typed action creators to create an action that is handled by the Effect.

> You see the only API you have to work with is the Ducks-API. It does not change anything in \[ngrx] but automates the process dealing with actions.
