Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NgRx Feature Creator
Search
Marko Stanimirović
September 02, 2022
Programming
240
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
NgRx Feature Creator
Marko Stanimirović
September 02, 2022
More Decks by Marko Stanimirović
See All by Marko Stanimirović
[NG India] Event-Based State Management with NgRx SignalStore
markostanimirovic
1
300
NgRx - Core Principles & New Features
markostanimirovic
0
660
Dependency Injection in Angular
markostanimirovic
0
240
NgRx Action Group Creator
markostanimirovic
1
800
NgRx Tips for Future-Proof Angular Apps
markostanimirovic
0
280
NgRx Store - Tips For Better Code Hygiene
markostanimirovic
1
190
Other Decks in Programming
See All in Programming
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
170
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
120
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
240
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
100
Creating Composable Callables in Contemporary C++
rollbear
0
200
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
490
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
170
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.4k
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
110
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
どこまでゆるくて許されるのか
tk3fftk
0
480
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
230
Featured
See All Featured
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
Code Reviewing Like a Champion
maltzj
528
40k
WENDY [Excerpt]
tessaabrams
11
38k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
A Soul's Torment
seathinner
6
3.1k
It's Worth the Effort
3n
188
29k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
480
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
220
WCS-LA-2024
lcolladotor
0
680
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Transcript
NgRx Feature Creator Marko Stanimirović
Marko Stanimirović @MarkoStDev ★ Sr. Frontend Engineer at JobCloud ★
NgRx Team Member ★ Angular Belgrade Organizer ★ Hobby Musician ★ M.Sc. in Software Engineering
What is NgRx Feature?
Reducer
Reducer Feature Name
Reducer Feature Name Selectors
Reducer Feature Name Selectors NgRx Feature
Creating NgRx Feature
export interface State { songs: Song[]; activeSongId: number | null;
isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; songs.reducer.ts
import { createReducer } from '@ngrx/store'; export interface State {
songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( ); songs.reducer.ts
import { createReducer } from '@ngrx/store'; export interface State {
songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, ); songs.reducer.ts
import { createReducer, on } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, on( SongsApiActions.songsLoadedSuccess, (state, { songs }) => ({ ==.state, songs, isLoading: false, }) ), on(** **. */) ); songs.reducer.ts
import { createReducer, on } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, on( SongsApiActions.songsLoadedSuccess, (state, { songs }) => ({ ==.state, songs, isLoading: false, }) ), on(** **. */) ); export const featureName = 'songs'; songs.reducer.ts
songs.module.ts import { StoreModule } from '@ngrx/store'; import * as
fromSongs from './songs.reducer'; @NgModule({ imports: [ StoreModule.forFeature( fromSongs.featureName, fromSongs.reducer ), ], }) export class SongsModule {} import { createReducer, on } from '@ngrx/store'; export interface State { songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, on( SongsApiActions.songsLoadedSuccess, (state, { songs }) => ({ ==.state, songs, isLoading: false, }) ), on(** **. */) ); export const featureName = 'songs'; songs.reducer.ts
import { createReducer, on } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, on( SongsApiActions.songsLoadedSuccess, (state, { songs }) => ({ ==.state, songs, isLoading: false, }) ), on(** **. */) ); export const featureName = 'songs'; songs.reducer.ts songs.selectors.ts
import { createReducer, on } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, on( SongsApiActions.songsLoadedSuccess, (state, { songs }) => ({ ==.state, songs, isLoading: false, }) ), on(** **. */) ); export const featureName = 'songs'; songs.reducer.ts import { createFeatureSelector, } from '@ngrx/store'; import * as fromSongs from './songs.reducer'; export const selectSongsState = createFeatureSelector<fromSongs.State>(fromSongs.featureName); songs.selectors.ts
import { createReducer, on } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const reducer = createReducer( initialState, on( SongsApiActions.songsLoadedSuccess, (state, { songs }) => ({ ==.state, songs, isLoading: false, }) ), on(** **. */) ); export const featureName = 'songs'; songs.reducer.ts import { createFeatureSelector, createSelector, } from '@ngrx/store'; import * as fromSongs from './songs.reducer'; export const selectSongsState = createFeatureSelector<fromSongs.State>(fromSongs.featureName); export const selectSongs = createSelector( selectSongsState, (state) => state.songs ); export const selectActiveSongId = createSelector( selectSongsState, (state) => state.activeSongId ); export const selectIsLoading = createSelector( selectSongsState, (state) => state.isLoading ); songs.selectors.ts
createFeature
songs.reducer.ts import { createFeature } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const songsFeature = createFeature({ });
songs.reducer.ts import { createFeature } from '@ngrx/store'; export interface State
{ songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const songsFeature = createFeature({ name: 'songs' });
songs.reducer.ts import { createFeature, createReducer, on } from '@ngrx/store'; export
interface State { songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const songsFeature = createFeature({ name: 'songs', reducer: createReducer( initialState, on(** **. */), on(** **. */) ), });
songs.reducer.ts import { createFeature, createReducer, on } from '@ngrx/store'; export
interface State { songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const songsFeature = createFeature({ name: 'songs', reducer: createReducer( initialState, on(** **. */), on(** **. */) ), }); const { name, =/ feature name reducer, =/ feature reducer selectSongsState, =/ feature selector selectSongs, =/ selector for `songs` property selectActiveSongId, =/ selector for `activeSongId` property selectIsLoading, =/ selector for `isLoading` property } = songsFeature;
songs.reducer.ts import { createFeature, createReducer, on } from '@ngrx/store'; export
interface State { songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const songsFeature = createFeature({ name: 'songs', reducer: createReducer( initialState, on(** **. */), on(** **. */) ), }); const { name, =/ feature name reducer, =/ feature reducer selectSongsState, =/ feature selector selectSongs, =/ selector for `songs` property selectActiveSongId, =/ selector for `activeSongId` property selectIsLoading, =/ selector for `isLoading` property } = songsFeature; songs.selectors.ts import { createSelector } from '@ngrx/store'; import { songsFeature } from './songs.reducer'; export const selectActiveSong = createSelector( songsFeature.selectSongs, songsFeature.selectActiveSongId, (songs, activeSongId) => songs.find((song) => song.id === activeSongId) );
songs.reducer.ts import { createFeature, createReducer, on } from '@ngrx/store'; export
interface State { songs: Song[]; activeSongId: number | null; isLoading: boolean; } const initialState: State = { songs: [], activeSongId: null, isLoading: false, }; export const songsFeature = createFeature({ name: 'songs', reducer: createReducer( initialState, on(** **. */), on(** **. */) ), }); const { name, =/ feature name reducer, =/ feature reducer selectSongsState, =/ feature selector selectSongs, =/ selector for `songs` property selectActiveSongId, =/ selector for `activeSongId` property selectIsLoading, =/ selector for `isLoading` property } = songsFeature; songs.module.ts import { StoreModule } from '@ngrx/store'; import { songsFeature } from './songs.reducer'; @NgModule({ imports: [ StoreModule.forFeature(songsFeature), ], }) export class SongsModule {} songs.selectors.ts import { createSelector } from '@ngrx/store'; import { songsFeature } from './songs.reducer'; export const selectActiveSong = createSelector( songsFeature.selectSongs, songsFeature.selectActiveSongId, (songs, activeSongId) => songs.find((song) => song.id === activeSongId) );
Marko Stanimirović @MarkoStDev Thank You!