ngxs-labs / emitter Goto Github PK
View Code? Open in Web Editor NEW:octopus: New pattern that provides the opportunity to feel free from actions
License: MIT License
:octopus: New pattern that provides the opportunity to feel free from actions
License: MIT License
@State<Auth>({
name: 'authState',
defaults: new Auth()
})
export class AuthState {
@Receiver()
public static add<T = Auth>(ctx: StateContext<T>, action: EmitterAction<T>): void {
ctx.patchState(action.payload);
}
}
describe('[TEST]: AuthState', () => {
let store: Store;
beforeEach(() => {
await TestBed.configureTestingModule({
imports: [AppTestingModule]
}).compileComponents();
});
beforeEach(() => {
store = TestBed.get(Store);
emitter = TestBed.get(StoreTestBed);
});
it('Should be correct ', fakeAsync(() => {
emitter.action(AuthState.add).emit({ token: 'test' }, () => tick(100));
expect(store.selectSnapshot(AuthState)).toEqual({ token: 'test' })
}));
});
When listening to actions from import { Actions } from '@ngxs/store'
and getting the action type with the import { getActionTypeFromInstance } from '@ngxs/store'
and having an interaction with another state in the called @receiver() action, the type
returned from getActionTypeFromInstance
behaves weird and in some scenarios mixes the types so that there's e.g:
Sometimes it's also always just the "ID 999" on all the types.
I'd expect it to be:
OR
or something similiar. Point is, a dispatched type
should also SUCCESSFUL, CANCELED or ERRORED
at some time.
I hope I explained this detailed enough. Just for clarification: This issue doesn't happen when using @action(). With @action() everything works as expected. It just happens with @receiver()
When using @receiver() in the first action and inside the first action then using dispatch(new OtherAction(...))
the issue also doesn't appear. Just when both are @receiver().
Here's also a reproduction on Stackblitz (check the console.logs, it only shows "CounterState", while it should show for 2 of the logs "OtherState"): https://stackblitz.com/edit/ngxs-emitter-example-dbv5fp?file=src%2Fapp%2Fstore%2Fother.state.ts
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ x] Other... Please describe:
This is an Angular issue but looking for help here as this is the suggest way to user the emitter in the docs.
export class BusinessState {
private static businessService: BusinessService;
private static userService: UserService;
constructor(
injector: Injector
) {
BusinessState.businessService = injector.get<BusinessService>(BusinessService);
BusinessState.userService = injector.get<UserService>(UserService);
}
This no longer works in Angular 9, produces the following error
Can't resolve all parameters for BusinessState: (?).
at getUndecoratedInjectableFactory (core.js:18801) [angular]
at injectableDefOrInjectorDefFactory (core.js:18785) [angular]
at providerToFactory (core.js:18851) [angular]
at providerToRecord (core.js:18835) [angular]
at R3Injector.processProvider (core.js:18651) [angular]
at :5001/vendor.js:59157:38 [angular]
at :5001/vendor.js:43540:76 [angular]
at Array.forEach (<anonymous>) [angular]
at deepForEach (core.js:1141) [angular]
at R3Injector.processInjectorType (core.js:18612) [angular]
at :5001/vendor.js:59134:30 [angular]
at :5001/vendor.js:43540:76 [angular]
at Array.forEach (<anonymous>) [angular]
at deepForEach (core.js:1141) [angular]
Libs:
- @angular/core version:~9.0.0-rc.5
- @ngxs/store version: ^3.5.1
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 10.13.0
- Platform: Windows
Others:
Hello,
After upgrading Angular to the latest, the emitter stopped working.
Everything is undefined, I assume that the @emitter cannot do its job at all.
Could you check it?
Thank you very much!
Norbert
What happens if this situation happens
@State<Array>({
name: 'list',
default: null
})
export class ListState {
@Resiver()
public static setList(ctx, action: EmitterAction<Array>) {
ctx.setState(action.payload);
}
}
class Component {
@Emitter(ListState.setList)
public setList: Emittable<any>;
ngOnInit() {
// I would like it to be the default value, as it was easy to do with actions
this.setList.emit();
}
}
It used to be so was in the action
export class AddListAction {
private readonly type: string = '[Add list] description';
constructor(public payload = []) {
}
}
@State({
name: 'list',
default: null
})
export class ListState {
@Resiver({ payload: [] }) // set default value when payload -> null | NaN | undefined
public static setList(ctx, action: EmitterAction<Array>) {
ctx.setState(action.payload);
}
}
example
@State<number>({
name: 'counter',
default: 0
})
export class CounterState {
@Resiver({ payload: 1 })
public static increment(ctx, { payload }: EmitterAction<number>) {
this.concatValue(ctx, payload);
}
@Resiver({ payload: -1 })
public static decrement(ctx, { payload }: EmitterAction<number>) {
this.concatValue(ctx, payload);
}
private static concatValue(ctx, payload): void {
ctx.setState(ctx.getState() + payload);
}
}
When making a POST request for creating a new entity x, using an injected service in my entity.state.ts
file, an Uncaught error
, with no details or further information, prevents the state from being persisted, even though the entity was successfully created / returned in the API response.
To make things more weird, intercepting the emittable with ofEmittableErrored()
and logging the error to the console puts the API response payload as the value for the error:
property, the emitted object from createEntity.emit(inputObject)
as the value for the payload:
property and sets the type:
property to the @Receiver({ type: x})
that I defined.
The API POST is returning 201
whilst the other API calls (that I have not had any issues with) are returning 200
.
Packages:
"@ngxs-labs/emitter": "^1.3.0"
"@ngxs/store": "3.2.0-dev.master-e5e34c9"
and tried with / without "@ngxs-labs/immer-adapter": "^1.0.0"
but the error still occurs.
Using:
"@angular/core": "7.0.3"
Node v10.13.0
Yarn 1.12.1
Where the scribbled out portion after Uncaught
is the API response.
Emitting another action inside one of the ofEmittable
filter cancel the others subscription.
Example :
this.actions$.pipe(
ofEmittableSuccessful(SampleState.setValue1),
tap(() => console.log('Success handler 1'))
).subscribe();
this.actions$.pipe(
ofEmittableSuccessful(SampleState.setValue1),
tap(() => console.log('Success handler 2')),
tap(() => this.emitter.action(SampleState.setValue2).emit(this.rdm()))
).subscribe();
this.actions$.pipe(
ofEmittableSuccessful(SampleState.setValue1),
tap(() => console.log('Success handler 3')),
tap(() => this.emitter.action(SampleState.setValue3).emit(this.rdm()))
).subscribe();
The first handler correctly write to the console.
The second handler emit the setValue2
action.
The third handler is never executed.
If I remove the emit from the 2nd handler, the third one is correctly executed.
Stackblitz : https://stackblitz.com/edit/ngxs-emitter-example-v6uhkr
I think this is related to #128.
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
Libs:
- @angular/core version: X.Y.Z
- @ngxs/store version: X.Y.Z
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
I'm not able to send payloads in the actions of the EmitterService.
Send payloads to the actions of the EmitterService without getting any problem
https://stackblitz.com/edit/ngxs-labs-emitter-aetrwj?file=src%2Fapp%2Fapp.component.ts
here... inline 25 of app.component.ts you will see the error.
"Argument of type 'number' is not assignable to parameter of type 'void'."
the changes in the emitter service in the last commit are causing this bug.
Fix a bug currently in version 2.0.0 (It use to work in 1.9.0)
Libs:
- @angular/core version: ~9.1.6
- @ngxs/store version: ^3.6.2
- @ngxs-labs/emitter: ^2.0.0
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: v12.16.3
- Platform: Mac
Others:
I also created a PR solving it... but I'm not able to push the changes...
So I'll show you where is the problem...
just search for my comments... thank you!
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
Same code worked OK until @ngxs-labs/emitter v1.9.0, as soon as updated to @ngxs-labs/emitter v2.0.0 it began throwing issues like the following (These cases contain errors with boolean data types, but same happens with any data type and the error output would contain the used data type like number, string, custom types etc):
app/modules/dashboards/modules/operator/app-skeleton-operator/app-skeleton-operator.component.ts:327:61 - error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'void'.
327 this.emitter.action(AppState.setLeftSidenavOpen).emit(opened);
~~~~~~
app/modules/dashboards/modules/operator/app-skeleton-operator/app-skeleton-operator.component.ts:331:78 - error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'void'.
331 tap(value => this.emitter.action(AppState.setLeftSidenavOpen).emit(!value)))
~~~~~~
app/modules/dashboards/modules/operator/app-skeleton-operator/app-skeleton-operator.component.ts:338:77 - error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'void'.
338 tap(value => this.emitter.action(AppState.setSidenavRightOpen).emit(!value)))
To have it working without issues
Libs:
- @angular/core version: 8.2.14
- @ngxs/store version: 3.6.1
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 10.15.3
- Platform: Linux
Others:
NOTE: I must confess I upgraded both @ngxs/store and other plugins to v3.6.1 and @ngxs-labs/emitter to v2.0.0 at the same time, so I'm not really sure whether the issue happens with @ngxs/store or @ngxs-labs/emitter packages.
I'm using NGXS in a production already (still under development also) app, that's why I took so long to upgrade.
Before NGXS concept
export class AddAnimal {
static readonly type = '[Zoo] Add Animal';
constructor(public name: string) {}
}
import { State } from '@ngxs/store';
@State<string[]>({
name: 'animals',
defaults: []
})
export class AnimalsState {
@Action(AddAnimal)
public add(ctx, action) {
ctx.setState([...ctx.getState(), action.payload]);
}
}
import { Store } from '@ngxs/store';
import { AddAnimal } from './animal.actions';
@Component({ ... })
export class ZooComponent {
constructor(private store: Store) {}
addAnimal() {
this.store.dispatch([
new AddAnimal('Panda'),
new AddAnimal('Zebra')
]);
}
}
After NGXS Labs concept
import { State } from '@ngxs/store';
@State<string[]>({
name: 'animals',
defaults: []
})
export class AnimalsState {
@Reciver()
public addAnimal(ctx, action) {
ctx.setState([...ctx.getState(), action.payload]);
}
}
import { Store } from '@ngxs/store';
import { AddAnimal } from './animal.actions';
@Component({ ... })
export class ZooComponent {
@Emitter(AnimalsState.addAnimal)
public animalValue: Emittable<string>;
addAnimal() {
this.animalValue.emitMany([ 'Panda', 'Zebra' ]);
}
}
@Receiver()
static showTrafficLayer ({ patchState }: StateContext<MapViewStateModel>, { payload }: EmitterAction<boolean>): void {
patchState ({ showTrafficLayer: payload });
}
Doesn't trigger changes to that property somewhere else in my code as defined with a Select decorator
@Select(MapViewState.showTrafficLayer) showTrafficLayer$: Observable<boolean>;
Hello everyone, I would like to make a proposal or a question.
Recently I saw the video Good Action Hygiene by Mike Ryan and Emitter pattern from ngxs-labs, and I would like to get what Mike Ryan talked about the actions but without the actions.
For example i have this in two different components:
Component Dashboard:
@Emitter(BurgerState.addBurguer)
public emitBurguerFromDashboard: Emittable<Burger>;
Component BurgerPage:
@Emitter(BurgerState.addBurger)
public emitBurgerFromBurgerPage: Emittable<Burger>;
but I want there to be only one implementation in the state, which in this case would be:
@Receiver()
public static addBurguer(ctx: StateContext<BurgerStateModel>, action: EmitterAction<Burger>) {
// logic.....
}
How to have all this but at the same time be able to see in my devtools:
[Dashboard] add burguer
[Burger Page] add burguer
Of course, without defining actions.
If it is not possible at this time, It would be great if I emit a payload and the source from which that payload came out, for example, something like that:
@Emitter({receiver: BurgerState.addBurguer, source: '[Dashboard] add burguer'})
public emitBurguerFromDashboard: Emittable<Burguer>;
@Emitter({receiver: BurgerState.addBurger, source: '[Burger Page] add burguer'})
public emitBurgerFromBurgerPage: Emittable<Burger>;
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
Is it possible to emit an Action directly via EmitterService, for example emit the Navigate
this.emitter.action(Navigate).emit({...})
@State<Application>({
name: 'application',
defaults: new Application()
})
export class ScheduleState {
private static store: Store;
@Emitter(ScheduleState.setSchedulePersons)
private static personEmitter: Emittable<{ [key: string]: Person }>;
constructor(store: Store) {
ScheduleState.store = store;
}
@Receiver()
public static async validateRequiredPerson({ getState }: StateContext<Application>) {
const state: Application = getState();
if (!state.manager.employeeId) {
const manager = this.store.selectSnapshot(ManagerState.getUser);
await this.personEmitter.emit({ manager }).toPromise();
}
if (!state.initiator.employeeId) {
const initiator = this.store.selectSnapshot(UserState.getUser);
await this.personEmitter.emit({ initiator }).toPromise();
}
}
}
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ x ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
import { EmitterAction, Receiver } from '@ngxs-labs/emitter';
@Receiver() public static setRegistered(ctx: StateContext<MasterStateModel>, action: EmitterAction<string>) {
the EmitterAction class cannot be found at runtime when compiled with Angular 9 -> ivy.
No bug at compile time.
Workaround:
@Receiver() public static setRegistered(ctx: StateContext<MasterStateModel>, action: any) {
any instead of EmitterAction
Should work with type EmitterAction
Libs:
- @angular/core version: X.Y.Z
- @ngxs/store version: X.Y.Z
` "dependencies": {
...
"@angular/compiler": "~9.0.0",
"@angular/core": "~9.0.0",
"@clr/angular": "^3.0.0-next.7",
"@clr/core": "^3.0.0-next.7",
"@clr/ui": "^3.0.0-next.7",
"@ngxs-labs/emitter": "~2.0.0",
"@ngxs/storage-plugin": "~3.6.2",
"@ngxs/store": "~3.6.2",
"@webcomponents/custom-elements": "~1.3.2",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},`
Browser:
- [ x ] Chrome (desktop) version Version 79.0.3945.130 (Official Build) (64-bit)
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
I found an example of a router integration, but I cannot use it because the Emittable
needs a static method, and I cannot use dependency injection in a static
context. Am I missing something?
I tried using the NgxsRouterPlugin
but it doesn't seem integrated in the Emittable
system, since it forces me to dependencyInject the Store
object.
How can I solve this situation?
export class Navigate {
static readonly type = '[router] navigate';
constructor(public payload: string) {
}
}
@State<string>({
name: 'router',
defaults: ''
})
export class RouterState {
constructor(private router: Router) {
}
@Action(Navigate)
async changeRoute(context: StateContext<string>, action: Navigate) {
const path = action.payload;
// context.setState(path);
await this.router.navigate([path]);
context.setState(path);
}
}
// or listen to an event stream ala NgRX Effects
// @Injectable()
// export class RouteHandler {
// constructor(private router: Router, private actions$: Actions) {
// this.actions$
// .pipe(ofAction(Navigate))
// .subscribe(({ payload }) => this.router.navigate([payload]));
// }
// }
Currently payload into EmitterAction
has type T | undefined
.
It would be handy to add a similar default action which does a runtime check about the payload being present and have type T
, leaving the user to chose what to use.
For now, I just manually typed the payload into the Receiver signature as { payload }: { payload: MyType }
@State<Todo[]>({
name: 'todos',
defaults: []
})
export class TodosState {
constructor(private api: ApiService) { }
@Emit() public static getTodosAction: Emittable<void>;
@Effect(TodosState.getTodosAction)
private getTodos({ setState }: StateContext<Todo[]>) {
return this.api.getTodos().pipe(tap((todos) => setState(todos)));
}
}
@Component({
selector: 'app-root',
template: `
<button (click)="addTodo.emit()">Add todo from server</button>
`
})
export class AppComponent {
public addTodo: Emittable<void> = TodosState.getTodosAction;
}
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[X] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
The emitter plugin TESTING is using a deprecated dependency with Angular 10.
When I'm trying to use this plugin with Angular 10. I want to run tests without issues.
When I'm using the out of the box solution for testing with the emitter. one of the dependencies. (ModuleWithProviders) now requires an argument. (The fix is quite small)...
In the file:
https://github.com/ngxs-labs/emitter/blob/master/emitter/testing/src/lib/store-test-bed.module.ts:10
should replace:
public static configureTestingModule(states: Type<any>[] = []): ModuleWithProviders[] {
with:
public static configureTestingModule(states: Type<any>[] = []): ModuleWithProviders<any>[] {
Be able to run a test suit in Angular 10.
Libs:
- @angular/core version: 10.0.0
- @ngxs/store version: 3.6.2
- @ngxs-labs/emitter version: 2.0.0
For Tooling issues:
- Node version: v12.16.3
- Platform: Mac
Что если бы мы декорировали не свойства класса, а параметры конструктора, то есть вместо этого:
class Component {
@Emitter(CounterState.increment)
private increment: Emittable<void>;
}
вот это:
class Component {
constructor(@Emitter(CounterState.increment) private increment: Emittable<void>) {}
}
@Component({ .. })
class MyComponent {
constructor(myState: MyState) {}
public increment(todo: string) {
this.myState.addTodo(todo);
}
}
@State({
name: 'hello',
..
})
export class MyState {
@Selector(MyState) public data$: Observable;
@Context() private ctx: StateContext<string[]>;
constructor(private api: ApiService) {}
@BindAction()
public addTodo(todo: string): void {
this.ctx.setState((state) => [...state, todo]);
}
@BindAction() // auto cancel uncompleted
public load(): Observable<void> {
return this.api.loadTodos().pipe(map((todos) => this.ctx.setState(todos)));
}
}
@Component({ .. })
class MyComponent {
constructor(myState: MyState) {}
public load() {
this.myState.load().subscribe(() => console.log('finish'));
}
}
@State({
name: 'hello',
..
})
export class MyState {
@Selector(MyState) public data$: Observable;
@Context() private ctx: StateContext<string[]>;
@Mutation() private mutator: StateMutator;
@BindAction()
public addTodo(todo: string): void {
this.ctx.setState((state) => {
return this.mutator(state, (draft) => draft.push(todo));
});
}
}
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:
Current multiple @Receiver
can't be used on one static method. This is not the case with @Action
where multiple @Action
can be used on one non-static method. There is an error throwing out in the console.
@Receiver
should have similar usage as @Action
yarn
.ng serve
.It will be for users to switch from @Action
to @Receiver
or vice versa without changing much of their codebase. In some situations users might want to listen to 2 different emitters but those emitters can have the same logic of updating state.
Libs:
- @angular/core version: 8.2.14
- @ngxs/store version: 3.5.1
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 10.17.0
- Platform: Windows 10 64bit
Others:
N.A.
For some reason when injecting the Emitter service or when emitting an action using decorators the state gets changed to "undefined", it is working correctly using the Store 3.3.4 but when updating to 3.4.1 I get the error, please check this stackblitz:
https://stackblitz.com/edit/ngxs-emitter-error
Thanks in advance.
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[x] Other... Please describe:
Regarding the distributed files of the npm package.
node_modules/@ngxs-labs/emitter/bundles/ngxs-labs-emitter.umd.js
(function (global, factory) {| (function (global, factory) {
typeof exports === 'object' && typeof module! == 'undefined'? factory (exports, require ('@ ngxs / store'), require ('@ angular / core'), require ('rxjs / operators') typeof exports === 'object' && typeof module! == 'undefined'? factory (exports, require ('@ ngxs / store'), require ('$
typeof define === 'function' && define.amd? define (['exports', '@ ngxs / store', '@ angular / core', 'rxjs / operators'], factory): | typeof define === 'function' && define.amd? define (['exports', '@ ngxs / store', '@ angular / core', 'rxjs / operators'] $
(global = global || self, factory ((global ['ngxs-labs'] = global ['ngxs-labs'] || {}, global ['ngxs-labs']. emitter = {}), global. ngxs.store, global.ng.core, global.rxjs.operators)); | (global = global || self, factory ((global ['ngxs-labs'] = global ['ngxs-labs'] || { }, global ['ngxs-labs']. emitter = $
} (this, function (exports, store, core, operators) {'use strict';
The ID that recognizes package is not passed when defining with define
function. For this reason, the following error occurs when launching a bundled application in Angular with AOT compilation (ngxs-labs-emitter.umd.min.js works correctly)
Current state:
define (['exports', '@ ngxs / store'...
Expected state:
define ('@ngxs-labs/emitter', ['exports', '@ ngxs / store'....
From browser console error:
Uncaught Error: Mismatched anonymous define() module: function (exports, store, core, operators) { 'use strict';
The umd file is created from the github code using the yarn emitter: build
command, the ID is correctly assigned, so there may be some problem in the package upload process.
When I subscribe to the actions$
observable and do multiple emits from the subscription, only the last one gets emitted, but multiple times.
actions$.pipe(
// same happens with ofActionDispatched/Successful
ofEmittableDispatched(CounterState.incrementAll),
switchMap(() => this.count$.pipe(first())),
tap((counter) => {
console.log("increment all");
this.counterValue.emit(counter.value + 1);
this.counterValue1.emit(counter.value1 + 1);
// only the last one gets dispatched, but 3 times
// one can work around it with setTimout or some kind of delay() operator
this.counterValue2.emit(counter.value2 + 1);
})
).subscribe();
Stackblitz:
https://stackblitz.com/edit/ngxs-emitter-example-gtdn6p
Before
After
@Emitter(UserState.update)
private userUpdate: Emittable<Person>;
public setInitiator() {
this.userUpdate.emit(person, { type: '[Set initiator]' });
}
public setManager() {
this.userUpdate.emit(person, { type: '[Set manager]' });
}
in console
action UserState.update [Set initiator] @ 15:52:20.922
action UserState.update [Set manager] @ 15:52:20.922
Before
export class AppComponent {
@Emitter(CounterState.increment)
private increment: Emittable<void>;
@Emitter(CounterState.decrement)
private decrement: Emittable<void>;
@Emitter(CounterState.throwError)
private throwError: Emittable<void>;
constructor(actions$: Actions) {
actions$.pipe(
ofEmittableDispatched(CounterState.increment)
).subscribe(() => {
console.log('CounterState.increment has been intercepted');
});
setInterval(() => {
this.increment.emit();
this.decrement.emit();
this.throwError.emit();
}, 1000);
}
}
After
export class AppComponent {
constructor(actions$: Actions, emitter: EmitterService) {
actions$.pipe(
ofEmittableDispatched(CounterState.increment)
).subscribe(() => {
console.log('CounterState.increment has been intercepted');
});
setInterval(() => {
emitter.action(CounterState.increment).emit();
emitter.action(CounterState.decrement).emit();
emitter.action(CounterState.throwError).emit();
}, 1000);
}
}
It would be really great if @Receiver
would also accept the cancelUncomplete configuration the same as @Action
does.
@Receiver({ cancelUncomplete: true })
Please add to documentation
I took it from examples that cause inconvenience to users.
@Receiver()
public static loadDocuments(
{ getState, patchState }: StateContext<BandejaStateModel>,
{ payload }: EmitterAction<BandejaFiltro>
) {
patchState({ ...getState(), bandejaFiltro: payload, pending: true });
return this.api.getBandeja(payload).pipe(
tap(docs =>
patchState({
bandejaFiltro: payload,
documentos: docs,
loaded: true,
pending: false
})
),
catchError(_err => {
patchState({
bandejaFiltro: payload,
documentos: [],
loaded: false,
pending: false
});
return of([]);
})
);
}
@State({
..
})
@Transaction({
rollback: MyState.rollback
})
class MyState {
@Receiver()
public static addOne(ctx, action) {
ctx.setState({ counter: 1 });
}
@Receiver()
public static addTwo(ctx, action) {
ctx.setState({ counter: 2 });
}
@Receiver()
public static addThree(ctx, action) {
ctx.setState({ counter: 3 });
ctx.setState({ counter: undefinedVariable }); // generate exception
}
@Rollback()
public rollback(ctx, action: RollbackAction<MyStateModel>) {
ctx.setState(action.payload); // { counter: 2 }, because MyState.addThree is bad
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.