SlideShare ist ein Scribd-Unternehmen logo
1 von 176
Downloaden Sie, um offline zu lesen
Tue, 22 Oct | 1:30 PM – 2:20 PM
Alpha Room
Iliya Idakiev

NGRX – Predictable Reactive State
Management Enterprise Angular Apps
A B O U T M E
{
"name": "Iliya Idakiev",
"experience": [
"Google Developer Expert (Angular/Web)",
"Developer & Co-founder @ HILLGRAND.com”,
"Lecturer in 'Advanced JS' @ Sofia University",
"Contractor / Consultant",
"Public / Private Courses"
],
"involvedIn": [
"Angular Sofia", "SofiaJS / BeerJS",
]
}
!
NGRX/PLATFORM
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPS
▸ State Management Problems.
▸ Observables vs Promises (Intro to RxJS).
▸ NGRX/Platform Overview.
▸ Creating a simple app using ngrx/store and ngrx/effects (v.8+).
▸ NGRX and State Management @ hillgrand.com
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHAT TO EXPECT
STATE MANAGEMENT
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
COMPONENT - SERVICE COMMUNICATION
Component
Class View
Class
Service (API)
ONE WEEK LATER…
Component
Class View
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
MULTI COMPONENT - SERVICE COMMUNICATION
Class
Service (API)
Component
Class View
ONE MONTH LATER…
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHERE SHOULD WE STORE STATE?
▸ Only inside the components.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHERE SHOULD WE STORE STATE?
▸ Only inside the components.
▸ Only inside the api services.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHERE SHOULD WE STORE STATE?
▸ Only inside the components.
▸ Only inside the api services.
▸ In both the components and the api services.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHERE SHOULD WE STORE STATE?
S.O.L.I.D
▸ The Single Responsibility Principle — Classes should have a single responsibility
and thus only a single reason to change.
▸ The Open/Closed Principle — Classes and other entities should be open for
extension but closed for modification.
▸ The Liskov Substitution Principle — Objects should be replaceable by their subtypes
▸ The Interface Segregation Principle — Interfaces should be client specific rather
than general.
▸ The Dependency Inversion Principle — Depend on abstractions rather than
concretions.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
SOLID PRINCIPLES OF OBJECT-ORIENTED DESIGN
▸ The Single Responsibility Principle — Classes should have a single responsibility
and thus only a single reason to change.
▸ The Open/Closed Principle — Classes and other entities should be open for
extension but closed for modification.
▸ The Liskov Substitution Principle — Objects should be replaceable by their subtypes
▸ The Interface Segregation Principle — Interfaces should be client specific rather
than general.
▸ The Dependency Inversion Principle — Depend on abstractions rather than
concretions.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
SOLID PRINCIPLES OF OBJECT-ORIENTED DESIGN
▸ Only inside the components.
▸ Only inside the api services.
▸ In both the components and the api services.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHERE SHOULD WE STORE STATE?
▸ Only inside the components.
▸ Only inside the api services.
▸ In both the components and the api services.
▸ Inside one or more store/state services.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
WHERE SHOULD WE STORE STATE?
REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
REDUX PATTERN
Component Action Reducer
Store
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
REDUX PATTERN WITH SELECTORS
Component Action Reducer
StoreSelector
▸ Unified way of handling state management.
▸ Single source of truth.
▸ Predictable state transitions due to the pure reducer functions.
▸ Easier to debug
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
BENEFITS
NGRX
▸ Framework for building reactive applications in Angular.
▸ NgRx provides:
▸ State management
▸ Isolation of side effects
▸ Entity collection management
▸ Router bindings
▸ Developer tools that enhance developers experience
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM EFFECTS
AND IT’S REACTIVE…
REACTIVE
Reacting to events or situations rather than acting first
to change or prevent something.
WHY IS IT REACTIVE?
RXJS
▸ RxJS is a library for reactive programming using
Observables, to make it easier to compose
asynchronous or callback-based code.
RXJS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
▸ RxJS is a library for reactive programming using
Observables, to make it easier to compose
asynchronous or callback-based code.
RXJS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
IS IT SOMETHING LIKE
PROMISES?
IT’S BETTER!
Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
PROMISE CHAIN
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
PROMISE CHAIN
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
PROMISE CHAIN
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
PROMISE CHAIN
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
▸ A state machine with three states - Unfulfilled / Resolved / Rejected.
▸ A Promise is a proxy for a value not necessarily known when the promise
is created.
▸ It allows you to associate handlers with an asynchronous action's
eventual success value or failure reason. (using .then / .catch)
▸ This lets asynchronous methods return values like synchronous methods:
instead of immediately returning the final value, the asynchronous
method returns a promise to supply the value at some point in the future.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
PROMISES
Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x);
// > Promise { value: '110' }
PROMISE FLATTENING
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Start the stream
1.OBSERVABLES ARE LAZY.
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
const sub = of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
sub.unsubscribe();
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
2.OBSERVABLES ARE
CANCELLABLE.
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
OBSERVABLES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
of(10).pipe(map(x => x + 100), map(x => '' + x)).subscribe(console.log);
OBSERVABLES WITH PIPEABLE OPERATORS (1)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { from } from 'rxjs';
import { map } from 'rxjs/operators';
const stream$ = from([1, 2, 3, 4]).pipe(map(x => x + 1));
stream$.subscribe(console.log)
// > 2
// > 3
// > 4
// > 5
MULTI VALUE OBSERVABLE (1)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { from } from 'rxjs';
import { map } from 'rxjs/operators';
const stream$ = from([1, 2, 3, 4]).pipe(map(x => x + 1));
stream$.subscribe(console.log)
// > 2
// > 3
// > 4
// > 5
MULTI VALUE OBSERVABLE (3)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { from } from 'rxjs';
import { map } from 'rxjs/operators';
const stream$ = from([1, 2, 3, 4]).pipe(map(x => x + 1));
stream$.subscribe(console.log)
// > 2
// > 3
// > 4
// > 5
MULTI VALUE OBSERVABLE (2)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
3.OBSERVABLES CAN EMIT
MULTIPLE VALUES.
3.1. DIFFERENT WAYS OF
EMITTING VALUES.

(COLD / HOT OBSERVABLES)
4.OBSERVABLES CAN BE CREATED
USING DIFFERENT CREATOR
FUNCTIONS.
5.BETTER FLOW CONTROL. 

(BY UNITISING THE LARGE MOUNT OF OPERATORS PROVIDED BY THE LIBRARY
OR CREATING OUR OWN OPERATORS)
6.CONTROLLING TIME. 

(BY USING THE DIFFERENT SCHEDULERS PROVIDED BY THE LIBRARY)
import { from } from 'rxjs';
import { map } from 'rxjs/operators';
const stream$ = from([1, 2, 3, 4]).pipe(map(x => x + 1));
stream$.subscribe(console.log)
// > 2
// > 3
// > 4
// > 5
CONTROLLING TIME (1)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { from, asyncScheduler } from 'rxjs';
import { map } from 'rxjs/operators';
const stream$ = from([1, 2, 3, 4], asyncScheduler).pipe(map(x => x + 1));
stream$.subscribe(console.log)
// > 2 (async)
// > 3 (async)
// > 4 (async)
// > 5 (async)
CONTROLLING TIME (2)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
RXJS IS REALLY POWERFUL.
NGRX IS REALLY
POWERFUL.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
import { createAction } from '@ngrx/store';
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX/store v.8
import { createAction } from '@ngrx/store';
export const loadUsers = createAction(
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createAction } from '@ngrx/store';
export const loadUsers = createAction(
'[USER LIST] Load Users'
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createAction } from '@ngrx/store';
export const loadUsers = createAction(
'[USER LIST] Load Users'
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Namespace
import { createAction } from '@ngrx/store';
import { actionType } from 'src/app/shared/action-type';
export const loadUsers = createAction(
'[USER LIST] Load Users'
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createAction } from '@ngrx/store';
import { actionType } from 'src/app/shared/action-type';
export const loadUsers = createAction(
  actionType('[USER LIST] Load Users')
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createAction } from '@ngrx/store';
import { actionType } from 'src/app/shared/action-type';
export const loadUsers = createAction(
  actionType('[USER LIST] Load Users')
);
export const loadUsersSuccess = createAction(
  actionType('[USER LIST] Load Users Success'),
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createAction } from '@ngrx/store';
import { actionType } from 'src/app/shared/action-type';
import { IUser } from 'src/app/shared/interfaces/user';
export const loadUsers = createAction(
  actionType('[USER LIST] Load Users')
);
export const loadUsersSuccess = createAction(
  actionType('[USER LIST] Load Users Success'),
  (users: IUser[]) => ({ payload: { users } })
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createAction } from '@ngrx/store';
import { actionType } from 'src/app/shared/action-type';
import { IUser } from 'src/app/shared/interfaces/user';
export const loadUsers = createAction(
  actionType('[USER LIST] Load Users')
);
export const loadUsersSuccess = createAction(
  actionType('[USER LIST] Load Users Success'),
  (users: IUser[]) => ({ payload: { users } })
);
export const loadUsersFailure = createAction(
  actionType('[USER LIST] Load Users Failure'),
  (error: Error) => ({ payload: { error } })
);
CREATING ACTIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
export interface IUserListState {   }
 
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
 
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
 
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = 
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
import { createReducer  } from '@ngrx/store';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX/store v.8
import { IUser } from 'src/app/shared/interfaces';
import { createReducer  } from '@ngrx/store';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers    } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers,  ),
  
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX/store v.8
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers, state =>  ),
  
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers  } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers, state => ({ ...state, isLoaded: false })),
  
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers, loadUsersSuccess } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers, state => ({ ...state, isLoaded: false })),
  on(loadUsersSuccess, ( ) => 
     )
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers, loadUsersSuccess } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers, state => ({ ...state, isLoaded: false })),
  on(loadUsersSuccess, (state, { payload: { users } }) => 
     )
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers, loadUsersSuccess } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers, state => ({ ...state, isLoaded: false })),
  on(loadUsersSuccess, (state, { payload: { users } }) => 
     )
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Automatic type detection
import { IUser } from 'src/app/shared/interfaces';
import { createReducer, on } from '@ngrx/store';
import { loadUsers, loadUsersSuccess } from '../actions/list';
export interface IUserListState { isLoaded: boolean; users: IUser[]; }
const initialState: IUserListState = { isLoaded: false, users: null };
export const reducer = createReducer<IUserListState>(
  initialState,
  on(loadUsers, state => ({ ...state, isLoaded: false })),
  on(loadUsersSuccess, (state, { payload: { users } }) => 
    ({ ...state, users, isLoaded: true }))
);
CREATING THE USER LIST REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
export const moduleReducerName = 'user';
CREATING THE USER MODULE REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
export const moduleReducerName = 'user';
export interface IUserState {
}
CREATING THE USER MODULE REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUserListState } from './list';
export const moduleReducerName = 'user';
export interface IUserState {
  readonly list: IUserListState;
}
CREATING THE USER MODULE REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { ActionReducerMap } from '@ngrx/store';
import { IUserListState } from './list';
export const moduleReducerName = 'user';
export interface IUserState {
  readonly list: IUserListState;
}
export const reducers: ActionReducerMap<IUserState> = {
};
CREATING THE USER MODULE REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { ActionReducerMap } from '@ngrx/store';
import { IUserListState } from './list';
import { reducer as listReducer } from '../reducers/list';
export const moduleReducerName = 'user';
export interface IUserState {
  readonly list: IUserListState;
}
export const reducers: ActionReducerMap<IUserState> = {
  list: listReducer
};
CREATING THE USER MODULE REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { ActionReducerMap } from '@ngrx/store';
import { IUserListState } from './list';
import { reducer as listReducer } from '../reducers/list';
export const moduleReducerName = 'user';
export interface IUserState {
  readonly list: IUserListState;
}
export const reducers: ActionReducerMap<IUserState> = {
  list: listReducer
};
CREATING THE USER MODULE REDUCER
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Feature State Name
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
@NgModule({
  declarations: [
…
  ],
  imports: [
…
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
CONFIGURING THE STORE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { StoreModule } from ‘@ngrx/store';
@NgModule({
  declarations: [
…
  ],
  imports: [
…
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
CONFIGURING THE STORE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { StoreModule } from ‘@ngrx/store';
@NgModule({
  declarations: [
…
  ],
  imports: [
…
    StoreModule.forRoot( ),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
CONFIGURING THE STORE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { StoreModule } from '@ngrx/store';
@NgModule({
  declarations: [
…
  ],
  imports: [
…
    StoreModule.forRoot({}),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
CONFIGURING THE STORE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { StoreModule } from '@ngrx/store';
@NgModule({
  declarations: […],
  imports: [
…
    StoreModule.forFeature(moduleReducerName, reducers)
  ]
})
export class UserModule { }
CONFIGURING THE FEATURE STORE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { StoreModule } from '@ngrx/store';
@NgModule({
  declarations: […],
  imports: [
…
    StoreModule.forFeature(moduleReducerName, reducers)
  ]
})
export class UserModule { }
CONFIGURING THE FEATURE STORE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Feature State Name (‘user’)
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
THE APP STATE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APP STATE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Feature State Name (‘user’)
THE APP STATE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APP STATE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUserListState } from '../reducers/list';
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector  } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector  } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState =  ;
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector( ,  );
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector(getUserModule,  );
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector(getUserModule, s => s.list);
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector(getUserModule, s => s.list);
export const getUserListStateIsLoaded = 
export const getUserListStateUsers = 
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector(getUserModule, s => s.list);
export const getUserListStateIsLoaded = 
createSelector( );
export const getUserListStateUsers = 
createSelector( );
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector(getUserModule, s => s.list);
export const getUserListStateIsLoaded = 
createSelector(getUserListState );
export const getUserListStateUsers = 
createSelector(getUserListState );
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { moduleReducerName, IUserState } from '../reducers';
import { IUserListState } from '../reducers/list';
export const getIsLoaded = (state: IUserListState) => state.isLoaded;
export const getUsers = (state: IUserListState) => state.users;
const getUserModule = 
createFeatureSelector<IUserState>(moduleReducerName);
const getUserListState = createSelector(getUserModule, s => s.list);
export const getUserListStateIsLoaded = 
createSelector(getUserListState, getIsLoaded);
export const getUserListStateUsers = 
createSelector(getUserListState, getUsers);
CREATING OUR FEATURE SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX






@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent {
  constructor( ) { }
}
USING OUR SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Store } from '@ngrx/store';
import { IAppState } from 'src/app/+store';






@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent {
  constructor(private store: Store<IAppState>) { }
}
USING OUR SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Store } from '@ngrx/store';
import { IAppState } from 'src/app/+store';
import {
  getUserListStateUsers,
} from '../+store/selectors';





@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent {
  users$ = this.store.select(getUserListStateUsers);
  constructor(private store: Store<IAppState>) { }
}
USING OUR SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Store } from '@ngrx/store';
import { IAppState } from 'src/app/+store';
import {
  getUserListStateUsers,
  getUserListStateIsLoaded
} from '../+store/selectors';





@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent {
  users$ = this.store.select(getUserListStateUsers);
  isLoaded$ = this.store.select(getUserListStateIsLoaded);
  constructor(private store: Store<IAppState>) { }
}
USING OUR SELECTORS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM REDUX
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import {   Actions    } from '@ngrx/effects';
@Injectable()
export class UserListEffects {
 
    
      
    
  
  constructor(private actions$: Actions ) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import {   Actions    } from '@ngrx/effects';
@Injectable()
export class UserListEffects {
  loadUsers$ = 
    
      
    
  
  constructor(private actions$: Actions ) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions  } from '@ngrx/effects';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(
    
      
    
   );
  constructor(private actions$: Actions ) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions  } from '@ngrx/effects';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    
      
    
   );
  constructor(private actions$: Actions ) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import {   loadUsers } from '../actions/list';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    
      
    
   );
  constructor(private actions$: Actions ) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import {   loadUsers } from '../actions/list';
import { switchMap  } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(
      
    
  ));
  constructor(private actions$: Actions ) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import {   loadUsers } from '../actions/list';
import { switchMap  } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => 
      
    
  ));
  constructor(private actions$: Actions ) { }
}
We will be returning an observable so
we need to flatten it to get the value
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import {   loadUsers } from '../actions/list';
import { UserService } from '../../user.service';
import { switchMap  } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.loadUsers()
      
    
  ));
  constructor(private actions$: Actions, private userService: UserService) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import {   loadUsers } from '../actions/list';
import { UserService } from '../../user.service';
import { switchMap  } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.loadUsers().pipe(
      
    )
  ));
  constructor(private actions$: Actions, private userService: UserService) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { loadUsersSuccess,   loadUsers } from '../actions/list';
import { UserService } from '../../user.service';
import { switchMap, map  } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.loadUsers().pipe(
      map( ),
    )
  ));
  constructor(private actions$: Actions, private userService: UserService) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { loadUsersSuccess,   loadUsers } from '../actions/list';
import { UserService } from '../../user.service';
import { switchMap, map  } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.loadUsers().pipe(
      map(users => loadUsersSuccess(users)),
    )
  ));
  constructor(private actions$: Actions, private userService: UserService) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { loadUsersSuccess,   loadUsers } from '../actions/list';
import { UserService } from '../../user.service';
import { switchMap, map, catchError } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.loadUsers().pipe(
      map(users => loadUsersSuccess(users)),
      catchError(     ))
    )
  ));
  constructor(private actions$: Actions, private userService: UserService) { }
}
CREATING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { loadUsersSuccess, loadUsersFailure, loadUsers } from '../actions/list';
import { UserService } from '../../user.service';
import { switchMap, map, catchError } from 'rxjs/operators';
@Injectable()
export class UserListEffects {
  loadUsers$ = createEffect(() => this.actions$.pipe(
    ofType(loadUsers),
    switchMap(() => this.userService.loadUsers().pipe(
      map(users => loadUsersSuccess(users)),
      catchError(error => [loadUsersFailure(error)]))
    )
  ));
  constructor(private actions$: Actions, private userService: UserService) { }
}
import { EffectsModule } from '@ngrx/effects';
@NgModule({
  declarations: [
…
  ],
  imports: [
…
    EffectsModule.forRoot([]),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
REGISTERING OUR ROOT EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
import { EffectsModule } from '@ngrx/effects';
@NgModule({
  declarations: […],
  imports: [
…
    EffectsModule.forFeature([UserListEffects])
  ]
})
export class UserModule { }
REGISTERING OUR FEATURE EFFECTS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
DEMO
▸ Listens for one or multiple actions and returns an action.
▸ Listens for one or multiple actions and returns nothing.
▸ Listens for one or multiple actions and returns multiple actions.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
TYPES OF EFFECT STREAMS
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
▸ @ngrx/store - state management.
▸ @ngrx/store-devtools - developer tools and instrumentation.
▸ @ngrx/effects - side effect isolation.
▸ @ngrx/router-store - Angular router bindings.
▸ @ngrx/entity - adapter for managing record collections.
▸ @ngrx/data - extension that simplifies management of entity data.
▸ @ngrx/schematics - scaffolding module for ngrx.
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM
@
import { createAction } from '@ngrx/store';
import { actionType } from 'src/app/shared/action-type';
import { IUser } from 'src/app/shared/interfaces/user';
export const loadUsers = createAction(
  actionType('[USER LIST] Load Users')
);
export const loadUsersSuccess = createAction(
  actionType('[USER LIST] Load Users Success'),
  (users: IUser[]) => ({ payload: { users } })
);
export const loadUsersFailure = createAction(
  actionType('[USER LIST] Load Users Failure'),
  (error: Error) => ({ payload: { error } })
);
REDUCING CODE BY EXTRACTING COMMON LOGIC INTO FACTORIES
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
NGRX / PLATFORM @ HILLGRAND.COM
MODELS
import { Component, OnInit } from '@angular/core';
import { ListModel } from ‘./+store/models/list.ts';



@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent implements OnInit {
  users$ = this.model.users$;
  isLoaded$ = this.model.isLoaded$;
  constructor(private model: ListModel) { }
ngOnInit() { this.model.loadUsers(); }
}
REDUCING CODE AND SHARING STATE DERIVATIONS BY USING MODELS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION STORE STRUCTURE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION STORE STRUCTURE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION STORE STRUCTURE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION STORE STRUCTURE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
THE APPLICATION STORE STRUCTURE
import { Injectable } from ‘@angular/core';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';



@Injectable()
export class SomeModel {
…
saveSuccess$ = this.actions$.pipe(
ofType(saveSuccess), mapTo(true)
);
  constructor(private actions$: Actions, private store: Store) { }
}
REDUCING STATE BY CREATING ACTION LISTENERS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Action Listeners
META REDUCERS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
We can think of meta-reducers as hooks into the action->reducer pipeline.
Meta-reducers allow us to pre-process actions before normal reducers are
invoked.
export function logoutStateCleaner(reducer) {
  return function (state: State, action: Action) {
    return reducer(action.type === logoutSuccess.type ? {
      router: state.router,
      // more things that you want to persist after logout
    } : state, action);
  };
}
NGRX-STORE-FREEZE IN DEVELOPMENT MODE
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
REDUCING STATE BY USING QUERY PARAMS
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
https://github.com/IliaIdakiev/
query-param-store
GitHub > https://github.com/iliaidakiev (/slides/ - list of future and past events)
Twitter > @ilia_idakiev
CONNECT
STATE MANAGEMENT FOR ENTERPRISE ANGULAR APPLICATIONS
Colour palette and background image + ngrx architecture image were taken from https://ngrx.io
THANK YOU!
Session
Feedback
Your Time & Opinion is Valued

https://www.telerik.com/devreach/day1feedback

Weitere ähnliche Inhalte

Was ist angesagt?

Marble Testing RxJS streams
Marble Testing RxJS streamsMarble Testing RxJS streams
Marble Testing RxJS streamsIlia Idakiev
 
State management for enterprise angular applications
State management for enterprise angular applicationsState management for enterprise angular applications
State management for enterprise angular applicationsIlia Idakiev
 
Predictable reactive state management for enterprise apps using NGRX/platform
Predictable reactive state management for enterprise apps using NGRX/platformPredictable reactive state management for enterprise apps using NGRX/platform
Predictable reactive state management for enterprise apps using NGRX/platformIlia Idakiev
 
Reactive Programming - ReactFoo 2020 - Aziz Khambati
Reactive Programming - ReactFoo 2020 - Aziz KhambatiReactive Programming - ReactFoo 2020 - Aziz Khambati
Reactive Programming - ReactFoo 2020 - Aziz KhambatiAziz Khambati
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 DreamLab
 
Higher-Order Components — Ilya Gelman
Higher-Order Components — Ilya GelmanHigher-Order Components — Ilya Gelman
Higher-Order Components — Ilya Gelman500Tech
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practicesClickky
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsMihail Gaberov
 
Redux in Angular2 for jsbe
Redux in Angular2 for jsbeRedux in Angular2 for jsbe
Redux in Angular2 for jsbeBrecht Billiet
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react applicationGreg Bergé
 
Redux data flow with angular 2
Redux data flow with angular 2Redux data flow with angular 2
Redux data flow with angular 2Gil Fink
 
Quick start with React | DreamLab Academy #2
Quick start with React | DreamLab Academy #2Quick start with React | DreamLab Academy #2
Quick start with React | DreamLab Academy #2DreamLab
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Nir Kaufman
 
State Models for React with Redux
State Models for React with ReduxState Models for React with Redux
State Models for React with ReduxStephan Schmidt
 
Async JavaScript Unit Testing
Async JavaScript Unit TestingAsync JavaScript Unit Testing
Async JavaScript Unit TestingMihail Gaberov
 
Codecamp iasi-26 nov 2011-what's new in jpa 2.0
Codecamp iasi-26 nov 2011-what's new in jpa 2.0Codecamp iasi-26 nov 2011-what's new in jpa 2.0
Codecamp iasi-26 nov 2011-what's new in jpa 2.0Codecamp Romania
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Mike Nakhimovich
 

Was ist angesagt? (20)

Marble Testing RxJS streams
Marble Testing RxJS streamsMarble Testing RxJS streams
Marble Testing RxJS streams
 
State management for enterprise angular applications
State management for enterprise angular applicationsState management for enterprise angular applications
State management for enterprise angular applications
 
Predictable reactive state management for enterprise apps using NGRX/platform
Predictable reactive state management for enterprise apps using NGRX/platformPredictable reactive state management for enterprise apps using NGRX/platform
Predictable reactive state management for enterprise apps using NGRX/platform
 
Reactive Programming - ReactFoo 2020 - Aziz Khambati
Reactive Programming - ReactFoo 2020 - Aziz KhambatiReactive Programming - ReactFoo 2020 - Aziz Khambati
Reactive Programming - ReactFoo 2020 - Aziz Khambati
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3
 
Higher-Order Components — Ilya Gelman
Higher-Order Components — Ilya GelmanHigher-Order Components — Ilya Gelman
Higher-Order Components — Ilya Gelman
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practices
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
 
Redux in Angular2 for jsbe
Redux in Angular2 for jsbeRedux in Angular2 for jsbe
Redux in Angular2 for jsbe
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react application
 
Redux data flow with angular 2
Redux data flow with angular 2Redux data flow with angular 2
Redux data flow with angular 2
 
Quick start with React | DreamLab Academy #2
Quick start with React | DreamLab Academy #2Quick start with React | DreamLab Academy #2
Quick start with React | DreamLab Academy #2
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
 
State Models for React with Redux
State Models for React with ReduxState Models for React with Redux
State Models for React with Redux
 
Async JavaScript Unit Testing
Async JavaScript Unit TestingAsync JavaScript Unit Testing
Async JavaScript Unit Testing
 
Redux workshop
Redux workshopRedux workshop
Redux workshop
 
Codecamp iasi-26 nov 2011-what's new in jpa 2.0
Codecamp iasi-26 nov 2011-what's new in jpa 2.0Codecamp iasi-26 nov 2011-what's new in jpa 2.0
Codecamp iasi-26 nov 2011-what's new in jpa 2.0
 
React lecture
React lectureReact lecture
React lecture
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
 

Ähnlich wie Enterprise State Management with NGRX/platform

(Micro?)services architecture in practice
(Micro?)services architecture in practice(Micro?)services architecture in practice
(Micro?)services architecture in practiceThe Software House
 
Functional Web Development
Functional Web DevelopmentFunctional Web Development
Functional Web DevelopmentFITC
 
From Big to Massive – Scalability in AngularJS Applications
From Big to Massive – Scalability in AngularJS ApplicationsFrom Big to Massive – Scalability in AngularJS Applications
From Big to Massive – Scalability in AngularJS ApplicationsSebastian Fröstl
 
AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...
AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...
AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...Amazon Web Services
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJosé Paumard
 
Autosys Trainer CV
Autosys Trainer CVAutosys Trainer CV
Autosys Trainer CVDS gupta
 
Moving existing apps to the cloud
 Moving existing apps to the cloud Moving existing apps to the cloud
Moving existing apps to the cloudRam Maddali
 
Cloud Native Architectures for Devops
Cloud Native Architectures for DevopsCloud Native Architectures for Devops
Cloud Native Architectures for Devopscornelia davis
 
Cloud Native: Designing Change-tolerant Software
Cloud Native: Designing Change-tolerant SoftwareCloud Native: Designing Change-tolerant Software
Cloud Native: Designing Change-tolerant Softwarecornelia davis
 
Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...Codemotion
 
Smart Services & Smart Clients - How Microservices Change the Way You Build a...
Smart Services & Smart Clients - How Microservices Change the Way You Build a...Smart Services & Smart Clients - How Microservices Change the Way You Build a...
Smart Services & Smart Clients - How Microservices Change the Way You Build a...Neil Mansilla
 
Modern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with NomadModern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with NomadMitchell Pronschinske
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to productionFDConf
 
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and KellMartineMccracken314
 
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and KellAbbyWhyte974
 
Human scaling on the front end
Human scaling on the front endHuman scaling on the front end
Human scaling on the front endRudy Rigot
 
Developer Intro to OpenShift
Developer Intro to OpenShiftDeveloper Intro to OpenShift
Developer Intro to OpenShiftTiera Fann, MBA
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJosé Paumard
 
An Application Centric Approach to Devops
An Application Centric Approach to DevopsAn Application Centric Approach to Devops
An Application Centric Approach to Devopsdfilppi
 

Ähnlich wie Enterprise State Management with NGRX/platform (20)

(Micro?)services architecture in practice
(Micro?)services architecture in practice(Micro?)services architecture in practice
(Micro?)services architecture in practice
 
Functional Web Development
Functional Web DevelopmentFunctional Web Development
Functional Web Development
 
From Big to Massive – Scalability in AngularJS Applications
From Big to Massive – Scalability in AngularJS ApplicationsFrom Big to Massive – Scalability in AngularJS Applications
From Big to Massive – Scalability in AngularJS Applications
 
AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...
AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...
AWS Sydney Summit 2013 - Continuous Deployment Practices, with Production, Te...
 
RIA
RIARIA
RIA
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
 
Autosys Trainer CV
Autosys Trainer CVAutosys Trainer CV
Autosys Trainer CV
 
Moving existing apps to the cloud
 Moving existing apps to the cloud Moving existing apps to the cloud
Moving existing apps to the cloud
 
Cloud Native Architectures for Devops
Cloud Native Architectures for DevopsCloud Native Architectures for Devops
Cloud Native Architectures for Devops
 
Cloud Native: Designing Change-tolerant Software
Cloud Native: Designing Change-tolerant SoftwareCloud Native: Designing Change-tolerant Software
Cloud Native: Designing Change-tolerant Software
 
Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...Maxim Salnikov - Service Worker: taking the best from the past experience for...
Maxim Salnikov - Service Worker: taking the best from the past experience for...
 
Smart Services & Smart Clients - How Microservices Change the Way You Build a...
Smart Services & Smart Clients - How Microservices Change the Way You Build a...Smart Services & Smart Clients - How Microservices Change the Way You Build a...
Smart Services & Smart Clients - How Microservices Change the Way You Build a...
 
Modern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with NomadModern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with Nomad
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
 
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
 
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
1. After reviewing chapters 9, 10, and 11 of the Kotler and Kell
 
Human scaling on the front end
Human scaling on the front endHuman scaling on the front end
Human scaling on the front end
 
Developer Intro to OpenShift
Developer Intro to OpenShiftDeveloper Intro to OpenShift
Developer Intro to OpenShift
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
An Application Centric Approach to Devops
An Application Centric Approach to DevopsAn Application Centric Approach to Devops
An Application Centric Approach to Devops
 

Mehr von Ilia Idakiev

Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JSIlia Idakiev
 
RxJS Schedulers - Controlling Time
RxJS Schedulers - Controlling TimeRxJS Schedulers - Controlling Time
RxJS Schedulers - Controlling TimeIlia Idakiev
 
Creating lightweight JS Apps w/ Web Components and lit-html
Creating lightweight JS Apps w/ Web Components and lit-htmlCreating lightweight JS Apps w/ Web Components and lit-html
Creating lightweight JS Apps w/ Web Components and lit-htmlIlia Idakiev
 
No More Promises! Let's RxJS!
No More Promises! Let's RxJS!No More Promises! Let's RxJS!
No More Promises! Let's RxJS!Ilia Idakiev
 
Deterministic JavaScript Applications
Deterministic JavaScript ApplicationsDeterministic JavaScript Applications
Deterministic JavaScript ApplicationsIlia Idakiev
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components EverywhereIlia Idakiev
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularIlia Idakiev
 
Offline progressive web apps with NodeJS and React
Offline progressive web apps with NodeJS and ReactOffline progressive web apps with NodeJS and React
Offline progressive web apps with NodeJS and ReactIlia Idakiev
 
Testing rx js using marbles within angular
Testing rx js using marbles within angularTesting rx js using marbles within angular
Testing rx js using marbles within angularIlia Idakiev
 
Angular server side rendering with NodeJS - In Pursuit Of Speed
Angular server side rendering with NodeJS - In Pursuit Of SpeedAngular server side rendering with NodeJS - In Pursuit Of Speed
Angular server side rendering with NodeJS - In Pursuit Of SpeedIlia Idakiev
 
Angular Offline Progressive Web Apps With NodeJS
Angular Offline Progressive Web Apps With NodeJSAngular Offline Progressive Web Apps With NodeJS
Angular Offline Progressive Web Apps With NodeJSIlia Idakiev
 
Introduction to Offline Progressive Web Applications
Introduction to Offline Progressive Web ApplicationsIntroduction to Offline Progressive Web Applications
Introduction to Offline Progressive Web ApplicationsIlia Idakiev
 

Mehr von Ilia Idakiev (13)

Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JS
 
RxJS Schedulers - Controlling Time
RxJS Schedulers - Controlling TimeRxJS Schedulers - Controlling Time
RxJS Schedulers - Controlling Time
 
Creating lightweight JS Apps w/ Web Components and lit-html
Creating lightweight JS Apps w/ Web Components and lit-htmlCreating lightweight JS Apps w/ Web Components and lit-html
Creating lightweight JS Apps w/ Web Components and lit-html
 
No More Promises! Let's RxJS!
No More Promises! Let's RxJS!No More Promises! Let's RxJS!
No More Promises! Let's RxJS!
 
Deterministic JavaScript Applications
Deterministic JavaScript ApplicationsDeterministic JavaScript Applications
Deterministic JavaScript Applications
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With Angular
 
Offline progressive web apps with NodeJS and React
Offline progressive web apps with NodeJS and ReactOffline progressive web apps with NodeJS and React
Offline progressive web apps with NodeJS and React
 
Testing rx js using marbles within angular
Testing rx js using marbles within angularTesting rx js using marbles within angular
Testing rx js using marbles within angular
 
Angular server side rendering with NodeJS - In Pursuit Of Speed
Angular server side rendering with NodeJS - In Pursuit Of SpeedAngular server side rendering with NodeJS - In Pursuit Of Speed
Angular server side rendering with NodeJS - In Pursuit Of Speed
 
Angular Offline Progressive Web Apps With NodeJS
Angular Offline Progressive Web Apps With NodeJSAngular Offline Progressive Web Apps With NodeJS
Angular Offline Progressive Web Apps With NodeJS
 
Introduction to Offline Progressive Web Applications
Introduction to Offline Progressive Web ApplicationsIntroduction to Offline Progressive Web Applications
Introduction to Offline Progressive Web Applications
 
Zone.js
Zone.jsZone.js
Zone.js
 

Kürzlich hochgeladen

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 

Kürzlich hochgeladen (20)

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 

Enterprise State Management with NGRX/platform