Giter Club home page Giter Club logo

emitter's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

emitter's Issues

Error when making a POST request to an API returning Status 201

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.
image

Add custom type for emit

image

image

Before

image

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

The id is not given to UMD package.

I'm submitting a...


[ ] 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:

Current behavior

Regarding the distributed files of the npm package.

https://www.npmjs.com/package/@ngxs-labs/emitter

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.

Action types wrong when subscribing for Action dispatch/success

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:

  1. DISPATCHED: [ID: 123]
  2. DISPATCHED: [ID: 999]
  3. SUCCESSFUL: [ID: 999]
  4. SUCCESSFUL: [ID: 999]

Sometimes it's also always just the "ID 999" on all the types.

I'd expect it to be:

  1. DISPATCHED: [ID: 123]
  2. DISPATCHED: [ID: 999]
  3. SUCCESSFUL: [ID: 999]
  4. SUCCESSFUL: [ID: 123]

OR

  1. DISPATCHED: [ID: 123]
  2. SUCCESSFUL: [ID: 123]
  3. DISPATCHED: [ID: 999]
  4. SUCCESSFUL: [ID: 999]

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

Emitter TESTING Angular 10 Dependency Deprecated

I'm submitting a...


[ ] 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 behavior

The emitter plugin TESTING is using a deprecated dependency with Angular 10.

Expected behavior

When I'm trying to use this plugin with Angular 10. I want to run tests without issues.

Minimal reproduction of the problem with instructions

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>[] {

What is the motivation/use case for changing the behaviour?

Be able to run a test suit in Angular 10.

Environment


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

Rollback action

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
 }

}

Multiple emits from actions$ observable has inconsistent behavior

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

Default value in payload

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 = []) {
  }
}

Proposal

@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);
 }

}

Angular 15 issue

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

add .emitMany([ ‘Panda’, ‘Zebra’ ]);

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' ]);
  }
}

Add EmitterService

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);
    }
}

Angular 9 (ivy) - ReferenceError: EmitterAction is not defined

I'm submitting a...


[ ] 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:

Current behavior

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.
image
No bug at compile time.

Workaround:
@Receiver() public static setRegistered(ctx: StateContext<MasterStateModel>, action: any) {

any instead of EmitterAction

Expected behavior

Should work with type EmitterAction

Minimal reproduction of the problem with instructions

  • install Angular 9 (ivy enabled by default)
  • write an emitter
  • write a receiver
  • compile (with ivy)
  • open browser
  • error

What is the motivation / use case for changing the behavior?

Environment


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:

Add example in documentation about how usage emit into state

@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();
    }

  }

}

Emit Action via EmitterService [Feature request]

I'm submitting a...


[ ] 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:

What is the motivation / use case for changing the behavior?

Is it possible to emit an Action directly via EmitterService, for example emit the Navigate

this.emitter.action(Navigate).emit({...})

Good Emitter Hygiene?

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>;

Add StoreTestBed for easy testing

@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' })
    }));
});

Emit action inside an action listener (with ofEmittableXXX) cancel others listeners

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.

@Select() of an @Receiver doesnt trigger change events

@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>;

Angular 9 dependency injection issue

I'm submitting a...


[ ] 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.

Current behavior

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]

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


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:

Add cancelUncomplete to @Receiver()

It would be really great if @Receiver would also accept the cancelUncomplete configuration the same as @Action does.

@Receiver({ cancelUncomplete: true })

Parameter decorator

Что если бы мы декорировали не свойства класса, а параметры конструктора, то есть вместо этого:

class Component {
    @Emitter(CounterState.increment)
    private increment: Emittable<void>;
}

вот это:

class Component {
    constructor(@Emitter(CounterState.increment) private increment: Emittable<void>) {}
}

API 2.0

Use case

@Component({ .. })
class MyComponent {
 constructor(myState: MyState) {}
 
 public increment(todo: string) {
   this.myState.addTodo(todo);
 }

}

BindAction

@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'));
 }

}

Immer mutation

@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));
    });
   }  

}

Version of EmitterAction where payload is always defined

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 }

error TS2345: Argument of type (boolean,number etc) is not assignable to parameter of type 'void'

I'm submitting a...


[ ] 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:

Current behavior

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)))

Expected behavior

To have it working without issues

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


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.

Support multiple receiver decorators on one static method

I'm submitting a...


[ ] 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 behavior

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.
image

Expected behavior

@Receiver should have similar usage as @Action

Minimal reproduction of the problem with instructions

  • Clone this repo
  • Install dependencies with yarn.
  • Run ng serve.
  • Observe the error in the console

What is the motivation / use case for changing the behavior?

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.

Environment


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.

EmitterService - Issue Sending Payload

I'm submitting a...


[ ] 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:

Current behavior

I'm not able to send payloads in the actions of the EmitterService.

Expected behavior

Send payloads to the actions of the EmitterService without getting any problem

Minimal reproduction of the problem with instructions

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.

What is the motivation/use case for changing the behaviour?

Fix a bug currently in version 2.0.0 (It use to work in 1.9.0)

Environment


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...

912e5f1

just search for my comments... thank you!

Routing doubt / Integration with NgxsRouterPlugin?

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?

image

Unusable example below

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]));
//   }
// }

SKIPPING OPTIONAL DEPENDENCY

I'm submitting a...


[ ] 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:

Current behavior

image

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


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:

Add Effect conception

@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;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.