ngrx / core Goto Github PK
View Code? Open in Web Editor NEWCore functionality for the ngrx platform
License: MIT License
Core functionality for the ngrx platform
License: MIT License
I am using EnterZone with @ngrx/effects
in order to get Angular to do change detection upon receiving data from Electron IPC. I noticed the operator immediately above .enterZone()
is not executed. (Using latest rxjs v5.4.0
.)
Here is my code:
import { Injectable, NgZone } from '@angular/core';
import { Actions, Effect, toPayload } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import '@ngrx/core/add/operator/enterZone';
import rxIpc from 'rx-ipc-electron/lib/renderer';
import * as player from './player.actions';
@Injectable()
export class PlayerEffects {
@Effect()
public openFile$: Observable<Action> = this.actions$
.ofType(player.LOAD_MEDIA_DIALOG)
.switchMap(() => rxIpc.runCommand('open-media-file', null))
.switchMap(files => {
if (!files) {
return Observable.empty();
}
return Observable.of(new player.SetSourceAction(files[0]));
})
.do(() => console.log('THIS IS NEVER EXECUTED.'))
.enterZone(this.zone);
constructor(
private zone: NgZone,
private actions$: Actions
) { }
}
I believe the easiest fix is to directly fork the rxjs do
operator and wrap all three subscriber callbacks in the zone.
I then add a select decorator will be useful when selecting from the store, please find the discussion
The shiny new A2 rc.7 uses rxjs beta 12. The ngrx/core dependency "rxjs": "5.0.0-beta.11"
produces an NPM warning.
An application here using rc.7 with current ngrx/store and /core appears to work fine, so this may need only the addition of a ^ in the package.json. But I did not run any test suites etc. to see if that is the case... hence this issue instead of a PR.
Hi,
I feel the source of this problem is in ngrx but I'm not 100% sure, at least it manifests itself with it…
Basically, since I updated my application from angular 4.0.0-rc.3 to 4.0.0-rc.5 (see https://gitlab.com/linagora/petals-cockpit/commit/d7caeefe44262442e33dd024682282037ba02982 for the exact changes), I can run ng serve
and then when I open the application with Chromium, I get the following error in the console:
polyfills.bundle.js:2717 Unhandled Promise rejection: Cannot convert undefined or null to object ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at combineReducers (vendor.bundle.js:55798)
at _initialReducerFactory (vendor.bundle.js:99193)
at AppModuleInjector.get (ng:///AppModule/module.ngfactory.js:146)
at AppModuleInjector.getInternal (ng:///AppModule/module.ngfactory.js:655)
at AppModuleInjector.NgModuleInjector.get (vendor.bundle.js:3542)
at _createReducerIfExtension (vendor.bundle.js:98799)
at AppModuleInjector.createInternal (ng:///AppModule/module.ngfactory.js:315)
at AppModuleInjector.NgModuleInjector.create (vendor.bundle.js:3523)
at NgModuleFactory.create (vendor.bundle.js:3496)
at vendor.bundle.js:4692
at ZoneDelegate.webpackJsonp.632.ZoneDelegate.invoke (polyfills.bundle.js:2513)
at Object.onInvoke (vendor.bundle.js:4083)
at ZoneDelegate.webpackJsonp.632.ZoneDelegate.invoke (polyfills.bundle.js:2512)
at Zone.webpackJsonp.632.Zone.run (polyfills.bundle.js:2273) TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at combineReducers (http://localhost:4200/vendor.bundle.js:55798:30)
at _initialReducerFactory (http://localhost:4200/vendor.bundle.js:99193:98)
at AppModuleInjector.get (ng:///AppModule/module.ngfactory.js:146:107)
at AppModuleInjector.getInternal (ng:///AppModule/module.ngfactory.js:655:71)
at AppModuleInjector.NgModuleInjector.get (http://localhost:4200/vendor.bundle.js:3542:44)
at _createReducerIfExtension (http://localhost:4200/vendor.bundle.js:98799:32)
at AppModuleInjector.createInternal (ng:///AppModule/module.ngfactory.js:315:22)
at AppModuleInjector.NgModuleInjector.create (http://localhost:4200/vendor.bundle.js:3523:76)
at NgModuleFactory.create (http://localhost:4200/vendor.bundle.js:3496:18)
at http://localhost:4200/vendor.bundle.js:4692:61
at ZoneDelegate.webpackJsonp.632.ZoneDelegate.invoke (http://localhost:4200/polyfills.bundle.js:2513:26)
at Object.onInvoke (http://localhost:4200/vendor.bundle.js:4083:37)
at ZoneDelegate.webpackJsonp.632.ZoneDelegate.invoke (http://localhost:4200/polyfills.bundle.js:2512:32)
at Zone.webpackJsonp.632.Zone.run (http://localhost:4200/polyfills.bundle.js:2273:43)
export interface SelectSignature<T = any> {
<R>(key: keyof T, ...paths: string[]): Observable<R>;
<R>(mapFn: (state: T) => R): Observable<R>;
}
So TypeScript can check for using the correct key at least on the top level:
export interface MyState {
myKey: any
}
...
Store<MyState> store;
store.select('myKey'); // fine
store.select('invalidKey'); // type error
I'm having the following errors:
ERROR in node_modules/@ngrx/core/src/compose.ts (12,43): Rest parameter 'functions' implicitly has an 'any[]' type.
node_modules/@ngrx/core/src/compose.ts (13,19): Parameter 'arg' implicitly has an 'any' type.
when using this repo with: Typescript 2.2.2 and the below tsconfig. From looking at the code there is a type annotation, but TS seems to be failing at inferring the types from it.
I've not dug into best-practices for publishing TS modules, but is the lack of explicit declaration file in package.json
, or a index.d.ts
forcing TypeScript to dig through the package and re-validate it? I note the TypeScript docs suggests either types
in package.json
or a index.d.ts
(the approach Angular itself takes).
{
"compilerOptions": {
"baseUrl": "",
"declaration": false,
"emitDecoratorMetadata": true,
"skipLibCheck": true,
"noImplicitAny": true,
"noEmitHelpers": true,
"importHelpers": true,
"strictNullChecks": false,
"noImplicitReturns": false,
"noImplicitThis": false,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"lib": ["es2016", "dom"],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}
The current version of ngrx/core (1.2.0) has a dependency to rxjs version "^5.0.0-beta.11" and a peer dependency to "^5.0.0-beta.12". Those a very deprecated versions (current latest version is 6.2.1) and cause my build to fail. Can you please update them?
Last night's new version of store and core include UMD bundles in the box. That's great, but there is a problem.
Store, as I write this, in the very first line of https://github.com/ngrx/store/blob/master/src/store.ts performs a deep import from core.
This runs into the exact same problem, when you try to actually use the UMD bundles, as we have seen with RxJS + UMD + SystemJS: the combination of UMD and the system loader is unable to "see" deep imports in a UMD. This problem was also present in Angular itself for quite a while, until numerous Angular source files were changed such that the various sub libraries import from each other at the top level only. Since the published RxJS API makes extensive use of deep imports, the solution there has been to just not attempt to use RxJS with system and UMD..
Possible solutions for NgRx:
I have been doing the latter, but it is an ugly hack I think... And that means I'm still making my own bundle of store instead of using the shiny new one in the box.
(Of course this only affects those neural cases where people care about loading all these libraries via UMDs. Demo apps. Plunkers. Training material, that one is my use case.)
4 export declare class SyncSubject extends Subject {
~~~~~~~~~~~
node_modules/@ngrx/core/SyncSubject.d.ts(4,22): error TS2415: Class 'SyncSubject' incorrectly extends base class 'Subject'.
Types of property '_subscribe' are incompatible.
Type '(subscriber: Subscriber) => AnonymousSubscription | Function | void' is not assignable to type '(subscriber: Subscriber) => Subscription'.
Type 'AnonymousSubscription | Function | void' is not assignable to type 'Subscription'.
Type 'AnonymousSubscription' is not assignable to type 'Subscription'.
Property 'isUnsubscribed' is missing in type 'AnonymousSubscription'.
A number of developers have asked if the ngrx organization would be willing to develop and maintain a reactive forms library for Angular.
Please use this ticket to report either A) usability issues with the existing reactive forms API found in @angular/forms, or B) present use cases that are not covered by @angular/forms.
Consider this step one in the design process of @ngrx/forms.
Hello dear community,
we encounter flakiness when executing unit tests in our project.
we would appreciate any help or input on that issue.
to reproduce that issue you will need to run the npm run test command multiple times - about 10x should be enough.
do-something.effects.spec.ts
and do-something.selectors.spec.ts
unit tests seem to run into fixture data conflict when executed multiple times.
do-something.selectors.spec.fixture.ts
import { DEFAULT_ROUTER_FEATURENAME, RouterReducerState } from '@ngrx/router-store';
import { IDoSomethingState } from '../../models/do-something-state';
import { Feature } from '../../models/event';
import { Foo } from '../../models/foo';
import * as fromDoSomething from './do-something.reducer';
interface ITestData {
readonly foo: Foo;
}
const testData: ITestData = {
foo: new Foo(
'second'
)
};
export class DoSomethingSelectorsFixture {
state: IDoSomethingState;
getStateForFeature() {
const mockRouterUrl = '/tab2/restore';
return {
[DEFAULT_ROUTER_FEATURENAME]: {
state: {
url: mockRouterUrl
}
} as RouterReducerState,
[Feature.DoSomething]: {
...fromDoSomething.initialState,
[mockRouterUrl]: this.state
}
};
}
setupDoSomethingState() {
this.state = {
foo: testData.foo,
bar: undefined
} as IDoSomethingState;
}
}
do-something.selectors.spec.ts
import { Foo } from '../../models/foo';
import { selectFoo } from './do-something.selectors';
import { DoSomethingSelectorsFixture } from './do-something.selectors.spec.fixture';
describe('DoSomethingFoo Selectors', () => {
describe('select foo', () => {
it('should return foo', () => {
// Arrange
const fixture = new DoSomethingSelectorsFixture();
fixture.setupDoSomethingState();
// Act
const result = selectFoo(fixture.getStateForFeature());
// Assert
expect(result).not.toBeNull();
expect(result).not.toBeUndefined();
expect(result).toEqual(fixture.state.foo as Foo);
});
});
});
do-something.effects.spec.fixture.ts
import { Bar, IBar } from '../../models/bar';
import { Foo } from '../../models/foo';
interface Fixture {
readonly foo: Foo,
readonly bar: IBar
}
export const fixture: Fixture = {
foo: new Foo(
'first'
),
bar: new Bar(
123
)
};
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { DEFAULT_ROUTER_FEATURENAME } from '@ngrx/router-store';
import { TypedAction } from '@ngrx/store/src/models';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { Observable, of } from 'rxjs';
import { DoSomethingApiService } from '../../api/do-something-api.service';
import { Feature } from '../../models/event';
import {
loadBar,
loadBarSuccess,
} from './do-something.actions';
import { DoSomethingEffects } from './do-something.effects';
import { fixture } from './do-something.effects.spec.fixture';
import {
selectFoo
} from './do-something.selectors';
describe('DoSomethingFooEffects', () => {
let actions$: Observable<TypedAction<string>>;
let effects: DoSomethingEffects;
let store: MockStore;
let apiService: DoSomethingApiService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{
path: 'tab2',
children: []
}
])
],
providers: [
DoSomethingEffects,
provideMockActions(() => actions$),
provideMockStore({
initialState: {
[DEFAULT_ROUTER_FEATURENAME]: {
state: {
url: '/myUrl',
},
},
[Feature.DoSomething]: {
['/myUrl']: undefined
}
},
}),
{
provide: DoSomethingApiService,
useFactory: (): Partial<DoSomethingApiService> => ({
getBarOfFoo: () => of(undefined)
}),
}
],
});
effects = TestBed.inject(DoSomethingEffects);
store = TestBed.inject(MockStore);
apiService = TestBed.inject(DoSomethingApiService);
});
describe('loadBarOfFoo', () => {
it('should return loadBarOfFooSuccess on success', async () => {
// Arrange
store.overrideSelector(selectFoo, fixture.foo);
spyOn(
apiService,
'getBarOfFoo'
).and.returnValue(of(fixture.bar));
actions$ = of(
loadBar({ url: 'test' })
);
// Act
const output =
await effects.loadBarOfFoo$.toPromise();
// Assert
expect(output).toEqual(
loadBarSuccess({
url: '/myUrl',
bar: fixture.bar,
})
);
});
});
});
Chrome Headless 98.0.4758.109 (Mac OS 10.15.7): Executed 0 of 2 SUCCESS (0
Chrome Headless 98.0.4758.109 (Mac OS 10.15.7): Executed 1 of 2 SUCCESS (0
Chrome Headless 98.0.4758.109 (Mac OS 10.15.7) DoSomethingFoo Selectors select foo should return foo FAILED
Error: Expected $.name = 'first' to equal 'second'.
at <Jasmine>
at UserContext.<anonymous> (src/app/features/do-something/do-something.selectors.spec.ts:19:22)
at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:400:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/zone-testing.js:301:43)
Chrome Headless 98.0.4758.109 (Mac OS 10.15.7): Executed 2 of 2 (1 FAILED) (0 secs / 0.055 secs)
Chrome Headless 98.0.4758.109 (Mac OS 10.15.7) DoSomethingFoo Selectors select foo should return foo FAILED
Error: Expected $.name = 'first' to equal 'second'.
at <Jasmine>
at UserContext.<anonymous> (src/app/features/do-something/do-something.selectors.spec.ts:19:22)
at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:400:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/zone-testi
Chrome Headless 98.0.4758.109 (Mac OS 10.15.7): Executed 2 of 2 (1 FAILED) (0.072 secs / 0.055 secs)
TOTAL: 1 FAILED, 1 SUCCESS
TOTAL: 1 FAILED, 1 SUCCESS
https://github.com/Olddude/flaky-selector-tests
Background: I'm using ngrx/store in my Angular2 app, which now requires this repo. I'm also using Webpack instead of SystemJS, and ES6 (transpiled using Babel) instead of Typescript.
In my karma unit testing setup, I'm using the source-map-loader Webpack plugin to optimize the stacktraces. However, @ngrx/core is causing the following warnings to be generated:
WARNING in ./~/@ngrx/core/SyncSubject.js
Cannot find source file '../../lib/SyncSubject.ts': Error: Cannot resolve 'file' or 'directory' ../../lib/SyncSubject.ts in /{REDACTED}/node_modules/@ngrx/core
WARNING in ./~/@ngrx/core/operator/select.js
Cannot find source file '../../../lib/operator/select.ts': Error: Cannot resolve 'file' or 'directory' ../../../lib/operator/select.ts in /{REDACTED}/node_modules/@ngrx/core/operator
It isn't preventing the tests from running or causing downstream problems, but I'm not having this problem with any other packages, so it seems to be specific to the way this package is set up.
I've stopped the warnings from being generated with the following settings in my Webpack config:
module: {
preLoaders: [
...
{test: /\.js$/, loader: 'source-map-loader', exclude: /(node_modules\/@ngrx\/core)/},
...
],
...
},
...but I figured I'd give a heads-up that I encountered this, in case anyone else runs into this in the future.
Can you please update package json files and sync dependency versions with current Angular 5 versions and dependencies? Right mos opf the ngrx dependencies are in discrepancy with Angular dependency versions.
Thanks
I'm trying to follow ngrx/core as a general guide for setting up a project for an angular2 library. After struggling with getting a simple test run to start, I cloned this repo and tried to run it's tests.
Tests fail to run with the following error from the console:
08 12 2016 16:42:35.115:ERROR [preprocess]: Can not load "webpack"!
<stack trace>
START:
Failed to parse file: ........\repositories\core\tests.bundle.ts
08 12 2016 16:42:35.163:ERROR [preprocessor.coverage]: Line 1: Unexpected token
at ......\repositories/core/tests.bundle.ts
08 12 2016 16:42:35.172:INFO [karma]: Karma v1.3.0 server started at http://localhost:9018/
08 12 2016 16:42:35.173:INFO [launcher]: Launching browser Chrome with unlimited concurrency
08 12 2016 16:42:35.174:ERROR [karma]: Found 1 load error
Nvm
The astute @robwormald once told me: "Everything is a stream, and thats fine you know?"
So lets make animations into streams. Not sure if this is the right place for this issue, but why not. Lets build some @ngrx/animate etc.
RxJs 6 changed the way operators are used on Observables, making them usable as functions inside .pipe().
LeaveZone is not comapatible with it
Hi,
I just ran into an issue:
When I call the compose function like this:
// this should return a root reducer;
return compose([
...metaReducers,
combineReducers,
])(reducers)(state, action);
}
Typescript compiles but throws on execution because it fails at destructuring the array of functions thus register the argument as an array.
But the compose signature says that i could use an array:
export interface ComposeSignature {
<A>(): (i: A) => A;
<A, B>(b: (i: A) => B): (i: A) => B;
<A, B, C>(c: (i: B) => C, b: (i: A) => B): (i: A) => C;
<A, B, C, D>(d: (i: C) => D, c: (i: B) => C, b: (i: A) => B): (i: A) => D;
<A, B, C, D, E>(e: (i: D) => E, d: (i: C) => D, c: (i: B) => C, b: (i: A) => B): (i: A) => E;
<A, B, C, D, E, F>(f: (i: E) => F, e: (i: D) => E, d: (i: C) => D, c: (i: B) => C, b: (i: A) => B): (i: A) => F;
(...fns: any[]): (input: any) => any; // <== this line
}
Alright, you could say that I can destructure the array by myself or NOT put functions into any array in the first place like this:
return compose(
...metaReducers,
combineReducers,
)(reducers)(state, action);
}
But it causes Typescript >= 2.4 to throw on compile:
Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures.
I found a workaround by doing so but it feels wrong to "cast" as any
return (compose(
...metaReducers,
combineReducers,
)(reducers) as any) (state, action);
}
The problem I think does not comes from your code because you do destructure functions:
https://github.com/ngrx/core/blob/master/src/compose.ts#L12
So maybe the issue comes from the typscript compiler or maybe there is something I don't understand.
Do you have any idea on what causes the array of function in the compose function not to work ?
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.