Skip to content

Instantly share code, notes, and snippets.

@otodockal
Last active October 31, 2022 11:51
Show Gist options
  • Save otodockal/cd2878316796cb5a7cb5e8f8b7732bd0 to your computer and use it in GitHub Desktop.
Save otodockal/cd2878316796cb5a7cb5e8f8b7732bd0 to your computer and use it in GitHub Desktop.
{
"Component Store": {
"prefix": "a-component-store",
"body": [
"import { Injectable } from '@angular/core';",
"import { ComponentStore, OnStateInit } from '@ngrx/component-store';",
"",
"export interface ${1:string}ComponentState {",
// status
"\tstatus: {",
"\t\tstate: 'loading' | 'loaded' | 'loaded_last' | null;",
"\t\ttype: 'success' | 'error' | null;",
"\t},",
// criteria
"\tcriteria: {",
"\t\tpage: number;",
"\t\tpageSize: number;",
"\t},",
// response
"\tresponse: ${2:unknown} | null",
"}",
"",
"@Injectable()",
"export class ${1:string}ComponentStore extends ComponentStore<${1:string}ComponentState> implements OnStateInit {",
"\tconstructor() {",
"\t\tsuper({",
// status
"\t\t\tstatus: {",
"\t\t\t\tstate: null,",
"\t\t\t\ttype: null,",
"\t\t\t},",
// criteria
"\t\t\tcriteria: {",
"\t\t\t\tpage: 1,",
"\t\t\t\tpageSize: 20,",
"\t\t\t},",
// response
"\t\t\tresponse: null",
"\t\t})",
"\t}",
// state init
"",
"\tngrxOnStateInit() {",
"\t\t// this.fetch();",
"\t}",
// body
"",
"\t/** SELECTORS */",
"\tprivate readonly status$ = this.select((state) => state.status);",
"\tprivate readonly criteria$ = this.select((state) => state.criteria);",
"\tprivate readonly response$ = this.select((state) => state.response);",
"",
// vm$
"\treadonly vm$ = this.select(",
"\t\tthis.status$,",
"\t\tthis.criteria$,",
"\t\tthis.response$,",
"\t\t(status, criteria, response) => ({",
"\t\t\tstatus,",
"\t\t\tcriteria,",
"\t\t\tresponse,",
"\t\t}),",
"\t\t{ debounce: true }",
"\t);",
"",
"\t/** UPDATERS */",
// setStatus
"\treadonly setStatus = this.updater((state, status: ${1:string}ComponentState['status']) => ({",
"\t\t...state,",
"\t\tstatus,",
"\t}));",
"",
// setCriteria
"\treadonly setCriteria = this.updater((state, criteria: Partial<${1:string}ComponentState['criteria']>) => ({",
"\t\t...state,",
"\t\tcriteria: {",
"\t\t\t...state.criteria,",
"\t\t\t...criteria,",
"\t\t},",
"\t}));",
"",
// setResponse
"\treadonly setResponse = this.updater((state, response: ${1:string}ComponentState['response']) => ({",
"\t\t...state,",
"\t\tresponse,",
"\t}));",
"",
"\t/** EFFECTS */",
"\t${3}",
"}"
]
},
"Component Store - Effect": {
"prefix": "a-component-store-effect",
"body": [
"readonly fetch = this.effect<Partial<${1:string}ComponentState['criteria']> | void>((value$) => {",
"\treturn value$.pipe(",
"\t\ttap((criteria) => {",
"\t\t\tif (criteria) {",
"\t\t\t\tthis.setCriteria(criteria);",
"\t\t\t}",
"\t\t\tthis.setStatus({",
"\t\t\t\tstate: 'loading',",
"\t\t\t\ttype: null",
"\t\t\t});",
"\t\t}),",
"\t\twithLatestFrom(this.criteria$),",
"\t\tswitchMap(([, criteria]) => ${2}of(null).pipe(",
"\t\t\ttapResponse(",
"\t\t\t\t(res) => {",
"\t\t\t\t\tthis.setResponse(res);",
"\t\t\t\t\tthis.setStatus({",
"\t\t\t\t\t\tstate: 'loaded',",
"\t\t\t\t\t\ttype: 'success',",
"\t\t\t\t\t});",
"\t\t\t\t},",
"\t\t\t\t() => {",
"\t\t\t\t\tthis.setStatus({",
"\t\t\t\t\t\tstate: 'loaded',",
"\t\t\t\t\t\ttype: 'error',",
"\t\t\t\t\t});",
"\t\t\t\t}",
"\t\t\t))",
"\t\t)",
"\t)",
"});"
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment