angular-redux / form Goto Github PK
View Code? Open in Web Editor NEWKeep your Angular2+ form state in Redux
License: MIT License
Keep your Angular2+ form state in Redux
License: MIT License
ngc
NodeJS Version:
Typescript Version:
Angular Version: 4.0.0
@angular-redux/store version: 6.1.0
@angular/cli version: (if applicable)
OS:
<form connect="sequences.assistantInfoForm" #assistantInfoForm="ngForm">
<ion-list>
<ion-list-header class="bg-light">
{{ "SEQ.DETAILS" | translate | uppercase }}
</ion-list-header>
<ion-item>
<ion-label color="primary" stacked>{{ "SEQ.NAME" | translate }}</ion-label>
<ion-input ngControl ngModel clearInput="true" type="text" name="name" required></ion-input>
</ion-item>
<ion-item>
<ion-label color="primary" stacked>{{ "SEQ.AREA" | translate }}</ion-label>
<ion-select ngControl ngModel name="area" required>
<ion-option *ngFor="let area of CONST.AREAS" value="{{area.id}}">{{ area.translation | translate }}</ion-option>
</ion-select>
</ion-item>
</ion-list>
</form>
<form connect="sequences.assistantInfoForm" #assistantInfoForm="ngForm">
<ion-list>
<ion-list-header class="bg-light">
{{ "SEQ.ACTIVITY_TYPE" | translate | uppercase }}
</ion-list-header>
<ion-item>
<ion-label>Red</ion-label>
<ion-radio ngControl ngModel name="color" value="red"></ion-radio>
</ion-item>
</ion-list>
</form>
Redux form also works with radio buttons
Can't manage to make it work
Runtime Error
Uncaught (in promise): Error: No value accessor for form control with name: 'color' Error: No value accessor for form control with name: 'color' at g (http://localhost:8100/build/polyfills.js:3:7133) at _throwError (http://localhost:8100/build/main.js:24117:11) at setUpControl (http://localhost:8100/build/main.js:24030:9) at http://localhost:8100/build/main.js:26152:13 at t.invoke (http://localhost:8100/build/polyfills.js:3:14529) at Object.onInvoke (http://localhost:8100/build/main.js:4499:37) at t.invoke (http://localhost:8100/build/polyfills.js:3:14469) at n.run (http://localhost:8100/build/polyfills.js:3:9741) at http://localhost:8100/build/polyfills.js:3:6774 at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15213) at Object.onInvokeTask (http://localhost:8100/build/main.js:4490:37) at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15134) at n.runTask (http://localhost:8100/build/polyfills.js:3:10390) at a (http://localhost:8100/build/polyfills.js:3:5313) at <anonymous>
Hello, I've been trying to add a radio button.
My question is, how to use angular redux forms with a radio button? I'm using Ionic 3.0
The normal text input and the select option work fine.
ngc
NodeJS Version: 8.11.1
Typescript Version: 2.3.4
Angular Version: 5.2.9
@angular-redux/store version: 7.1.1
@angular/cli version: (if applicable) 1.2.6
OS: mac
(optional, but helps a lot)
Reflect the value from redux store in the form template without changing the value on initial component load.
When the form loads, there is a property in redux store that has initial value of 'false', but when the component is initiated, I can inspect in redux tools, that @@angular-redux/form/FORM_CHANGED changes the value to empty string. It is a checkbox component. When I try to manually switch in on/off, the correct value is being sent to the server. Any ideas why is that happening?
n/a
Please let me know if you need any other info about the issue
@angular/cli
NodeJS Version: v6.11.1
Typescript Version: 2.4.2
Angular Version: 4.3.2
@angular-redux/store version 6.5.7:
@angular/cli version: 1.4.0-rc.1
OS: Ubuntu 16.04
component
showing the issueimport { Component } from '@angular/core'
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app',
template: `
<form connect="forms" [formGroup]="myFormGroup">
<input
type="text"
name="email"
formControlName="email"
/>
</form>
`,
})
export class FormGenComponent {
public myFormGroup: FormGroup;
constructor() {
this.myFormGroup = new FormGroup({
email: new FormControl(),
});
}
}
I am using redux-devtools-extension to debug my actual store. There it is possible to go to a previous state at any time.
I want that this form updates when I change the state with the devtools (it works without the FormGroup
though)
The input field does not change the value according to the store.
None.
As soon as I am using the FormGroup
I can't go back to a previous state. The paths in formControlName
should be valid. I don't really get the documentation here. I am not sure if that is a bug, since it could be that my implementation is wrong.
angular-redux/form
exposes a composeReducers
function. Can you elaborate on what this does that isn't normally handled via Redux's existing combineReducers
?
ngc
NodeJS Version: latest
Typescript Version: lastest
Angular Version: latest
@angular-redux/store version: latest
@angular/cli version: (if applicable) latest
OS:
Unit test work without errors
TypeError: Cannot read property 'getState' of null
Hi,
When I run my unit tests, I get TypeError: Cannot read property 'getState' of null
Error in the terminal / console. The tests actually pass, but the errors are still confusing. Maybe this is a lack of understanding or it's an actual bug.
I am using the connect directive in this format:
<form [connect]="['shops', 'form']">
<label>Partner ID: </label>
<input type="number" name="shopId" ngControl ngModel/>
</form>
because I need the state to be part of a sub module path.
My .spec.ts file looks like this:
import { FormsModule } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MockNgRedux, NgReduxTestingModule } from '@angular-redux/store/testing';
import { NgReduxFormModule } from '@angular-redux/form';
import { FormComponent } from './form.component';
import { ShopActions } from '../store/shops.actions';
const mockShopActions = {
setShop: () => {
},
shopLoaded: () => {
},
};
describe('FormComponent', () => {
let component: FormComponent;
let fixture: ComponentFixture<FormComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
NgReduxTestingModule,
NgReduxFormModule
],
declarations: [FormComponent],
providers: [
{ provide: ShopActions, useValue: mockShopActions }
]
}).compileComponents();
MockNgRedux.reset();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Here is the complete Error trace:
TypeError: Cannot read property 'getState' of null
at MockNgRedux.NgRedux.getState (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:27537:58)
at FormStore.Array.concat.FormStore.getState (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:22217:27)
at Connect.Array.concat.Connect.getState (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:30142:27)
at http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:30131:49
at Array.forEach (native)
at Connect.Array.concat.Connect.resetState (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:30129:18)
at http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:30092:19
at ZoneDelegate.invoke (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2764:26)
at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:63940:39)
at ZoneDelegate.invoke (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2763:32)
at Object.onInvoke (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:4622:37)
at ZoneDelegate.invoke (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2763:32)
at Zone.run (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2524:43)
at http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:3157:57
at ZoneDelegate.invokeTask (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2797:31)
at resolvePromise (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:3109:31) [angular]
at http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:3160:17 [angular]
at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvokeTask (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:63964:39) [angular]
at Object.onInvokeTask (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2675:100) [angular]
at Object.onInvokeTask (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:4613:37) [angular]
at drainMicroTaskQueue (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2990:35) [<root>]
at ZoneTask.invoke (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2863:25) [<root>]
at timer (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:4054:29) [<root>]
at ____________________Elapsed_4_ms__At__Tue_May_09_2017_19_37_21_GMT_0200__CEST_ (http://localhost)
at getStacktraceWithUncaughtError (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:63719:12) [angular]
at new LongStackTrace (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:63713:22) [angular]
at Object.onScheduleTask (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:63789:22) [angular]
at Object.onScheduleTask (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:2673:29) [angular]
at scheduleResolveOrReject (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:3155:14) [angular]
at ZoneAwarePromise.then (http://localhost:9876/base/src/polyfills.ts?bdd59f38a06b817981b3da211939e6141b2452a4:3244:17) [angular]
at Connect.Array.concat.Connect.ngAfterContentInit (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:30091:27) [angular]
at callProviderLifecycles (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:11537:18) [angular]
at callElementProvidersLifecycles (http://localhost:9876/base/src/test.ts?ac69261a7f71dfd7ceb4ff33a2a00c39d09bbc33:11518:13) [angular]
It looks to me as if the the nested state object is not present, when the connect class cycles through the path children.
Is there a way to tell MockNgRedux what the state object should consist of? Or am I simply doing something wrong?
@angular-redux/form needs a revamp. Since we've started working on a 7.0.0 release roadmap for /[email protected] (https://github.com/angular-redux/store/projects/2) this seems like a good opportunity to re-work /form in the same timeframe.
Angular CLI: 6.0.8
Node: 8.9.4
OS: win32 x64
Angular: 6.0.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.6.8
@angular-devkit/build-angular 0.6.8
@angular-devkit/build-optimizer 0.6.8
@angular-devkit/core 0.6.8
@angular-devkit/schematics 0.6.8
@angular/cli 6.0.8
@ngtools/webpack 6.0.8
@schematics/angular 0.6.8
@schematics/update 0.6.8
rxjs 6.2.0
typescript 2.7.2
webpack 4.8.3
Connect to an empty form without issue.
After upgrading 6.6.0 => 9.0.1, if the initial state of the form was null, it would crash on trying to connect before any state changes were made; it's now expecting initial values when before it didn't care. If this is intended, then it would be good to have it documented as before I had a form as null until an @angular-redux/form action was fired.
State.traverse line 26 (e.g. can't call on a null object).
Another
core.js:1542 ERROR Error: Uncaught (in promise): Error: Must supply a value for form control with name: '<formControlName>'. Error: Must supply a value for form control with name: '<formControlName>'.
We used @angular-redux/form in a production-level application that is using @angular-redux/form 6.6.0 and Angular 5.2.6 and are trying to upgrade it to Angular 6 for access to i18n.
NodeJS Version: latest
Typescript Version: latest
Angular Version: latest
@angular-redux/store version: latest
@angular/cli version: (if applicable)
OS: Linux
Could you provide an example of how to use immutable store state with angular forms?
@angular-redux/form declares that ImmutableJS integration is provided seamlessly, but I cannot get it work.
I have problem with @angular/forms which does not work if I connect a form with immutable instance (Map or Record).
I would say that forms does not support ImmutableJS as 'model' (because of FormGroup.prototype._checkAllValuesPresent
) and maybe I should ask this at @angular/forms, but as long as you declare that you support it, I think that I am doing something wrong.
NodeJS Version: 6.9.2
Typescript Version: 2.2.2
Angular Version: 4.2
@angular-redux/store version: 3.10.9
@angular/cli version: (if applicable) 1.3.0
OS: win32 x64
Hi,
I'm using angular-redux/form with angular-redux/store and Reactive Forms. It works fine. State is updated when changing inputs in the form.
The problem now is, that the connect-Directive does indeed allow passing a function - but this function does not receive the state object (as it does e.g. in the NgRedux.select-function of angular-redux/store).
In my use-case, state looks like this:
{
currentItemId: 42,
items: [
{
itemId: 41,
name: "Item41"
},
{
itemId: 42,
name: "Item42"
},
{
itemId: 43,
name: "Item43"
}
]
}
So I would like to ´connect´ the currentItem
to my input-form
With NgRedux
i can
ngRedux.select<ItemState>(state => state.items.filter(i=>i.itemId === state.currentItemId))[0].subscribe(...)
in order to subscribe to changes to the current item.
In angular-redux/forms, I cannot achieve this using a string or an array of strings to select the path for the connect-directive, since I cannot choose the correct item-object with this syntax? I would like to be able to use the same lambda as in the example for NgRedux in my connect-Directive of my form.
Any other solutions?
Trying to run the examples - Chrome is complaining about CORS from mocky.io:
XMLHttpRequest cannot load http://www.mocky.io/v2/588d702d100000d50f2d2980. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
I note that it is only on the intial load, the app routes to /elephants
and this is where the error occurs.
Subsequent clicks to elephants
is fine.
NodeJS Version: 8.2.1
Typescript Version: 2.3.4
Angular Version: 4.0.0
@angular-redux/store version: 6.5.7
@angular/cli version: 1.2.1
OS: Linux Mint 18.2
How do you implement form validation? I want my required fields to have the have separate validation state, which attaches has-error
in bootstrap's form-group
class, to showcase the error.
I believe update on documentation would be good. Following your guide I stumbled upon the "Unexpected keys found in state, received by reducer" warning. I got rid of it by implicitly passing the "unexpected" keys to combineReducers
function, with value of (state = {}) => state
. That silenced the warning and I think it should be noted in the docs.
ngc
NodeJS Version: 10.14.1
Typescript Version: 3.1.4
Angular Version: 7.1.2
@angular-redux/store version: 9.0.0
@angular/cli version: (if applicable) 7.1.2
OS: Windows 10/ MacOs
(optional, but helps a lot)
When a connected form is initialized where values are already set in the store (such as opening a form to edit some previously set value, or going back in browser history to a previous page) the values in the form model should be updated to reflect the values in the store?
When a connected form is initialized where the values are already set in the store, the values in the DOM are populated but the form model is not updated until editing the form or triggering change detection some other way. Should this type of pattern work or do I need to check for the values in the store when initializing the form and set them explicitly?
@angular/cli
ngc
NodeJS Version: 8.9.4
Typescript Version: 2.5.3
Angular Version: 5.2.3
@angular-redux/store version: 7.0.2
@angular/cli version: (if applicable): 1.6.5
OS: Windows 10
Angular form to initialize as normal.
Upon initializing my form, e.g.:
import { FormBuilder, FormGroup } from '@angular/forms';
. . .
constructor(private fb: FormBuilder) {
}
ngOnInit() {
// initialize form
this.form = this.fb.group({
firstName: [this.firstName],
lastName: [this.lastName],
nameSuffix: [this.nameSuffix],
middleName: [this.middleName],
nickName: [this.nickName],
});
}
it throws a very uninformative error on only some forms during initialization -- some work okay.
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'firstName' of null
TypeError: Cannot read property 'firstName' of null
at Function.State.traverse (state.js:26)
at Function.State.get (state.js:44)
at eval (connect-base.js:92)
at Array.forEach (<anonymous>)
at ReactiveConnect.ConnectBase.resetState (connect-base.js:90)
at eval (connect-base.js:43)
at ZoneDelegate.invoke (zone.js:388)
at Object.onInvoke (core.js:4733)
at ZoneDelegate.invoke (zone.js:387)
at Zone.run (zone.js:138)
at Function.State.traverse (state.js:26)
at Function.State.get (state.js:44)
at eval (connect-base.js:92)
at Array.forEach (<anonymous>)
at ReactiveConnect.ConnectBase.resetState (connect-base.js:90)
at eval (connect-base.js:43)
at ZoneDelegate.invoke (zone.js:388)
at Object.onInvoke (core.js:4733)
at ZoneDelegate.invoke (zone.js:387)
at Zone.run (zone.js:138)
at resolvePromise (zone.js:809)
at eval (zone.js:861)
at ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:4724)
at ZoneDelegate.invokeTask (zone.js:420)
at Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
at <anonymous>
It took me a while to track down that it was related to a form issue. Once I discovered it was a form issue, I started looking into what had changed. My update to @angular-redux/form 6.7.0 from 6.6.0 seemed to be the culprit. I downgraded and it worked as intended, then upgraded back to 6.7.0 and I get the same "random" error [can't figure out why it works on some forms, but not others -- but the forms it fails on, it fails on every time].
I also found that of the forms that worked, if there were any hidden form elements that I was sending to the store along with other form changes, these were no longer sending to the store as a direct result of this update.
npm install angular-redux/form --save
> @angular-redux/[email protected] postinstall \node_modules\@angular-redux\form
> npm run build
> @angular-redux/[email protected] prebuild \node_modules\@angular-redux\form
> npm run clean
> @angular-redux/[email protected] clean \node_modules\@angular-redux\form
> rimraf dist
> @angular-redux/[email protected] build \node_modules\@angular-redux\form
> ngc
Error at ......../node_modules/@angular-redux/form/source/state.ts:221:25: Type 'string' does not satisfy the constraint 'object'.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @angular-redux/[email protected] build: `ngc`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @angular-redux/[email protected] build script 'ngc'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the @angular-redux/form package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! ngc
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs @angular-redux/form
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls @angular-redux/form
npm ERR! There is likely additional logging output above.
@angular/cli
NodeJS Version: 6.10.0
Typescript Version: 2.5.3
Angular Version: 4.2.0
@angular-redux/store version: 6.5.7
@angular/cli version: (if applicable): 1.4.7
OS: Windows
Currently, I am utilizing angular-redux/form
to capture my form data and I have validators in the reducer in order to keep all my logic within the reducer. Each time a value is entered into the form, my reducer listens to the @@angular-redux/form/FORM_CHANGED
action that is fired by angular-redux/form
and then performs validations against the inputs and changes state accordingly to give messages or whatever. Everything works great, except that the reaction is instantaneous and I would like the ability to debounce the user entries so they don't get insta-error messages for a better user experience.
I could accomplish this by subscribing to the .onValueChanges
on the form with a debounce, which then fires off a custom action, which then does the validation. This seemingly defeats most of the purpose of the angular-redux/form
and seems like extra work when I could just listen to the @@angular-redux/form/FORM_CHANGED
and check the payload.path
in order to determine what form is being acted upon. Additionally, it adds even more action spam in the store, when I feel like a simple debounce would create less, allow one to utilize the strengths of angular-redux/form [less work], and give the desired effect. [Do you have any better suggestions on how to handle this?]
It would make sense to offer a feature within angular-redux/form
that allows specific inputs to be debounced instead of every keystroke instantly saving to the store (so the actual dispatch action is delayed).
When trying to add it to my project using:
npm install @angular-redux/form
I'm getting the following error:
Asafs-MBP:MyProject asafron$ npm install @angular-redux/form
@angular-redux/[email protected] postinstall /Documents/MyProject/node_modules/@angular-redux/form
npm run build
@angular-redux/[email protected] prebuild /Documents/MyProject/node_modules/@angular-redux/form
npm run clean
@angular-redux/[email protected] clean /Documents/MyProject/node_modules/@angular-redux/form
rimraf dist
@angular-redux/[email protected] build /Documents/MyProject/node_modules/@angular-redux/form
ngc
Error at /Documents/MyProject/node_modules/@angular-redux/form/source/state.ts:221:25: Type 'string' does not satisfy the constraint 'object'.
npm ERR! Darwin 16.4.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build"
npm ERR! node v6.9.1
npm ERR! npm v4.0.5
npm ERR! code ELIFECYCLE
npm ERR! @angular-redux/[email protected] build: ngc
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @angular-redux/[email protected] build script 'ngc'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the @angular-redux/form package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! ngc
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs @angular-redux/form
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls @angular-redux/form
npm ERR! There is likely additional logging output above.
Currently this project does not support Angular 5.0.
Is there any pre-release that does?
What do we need to change to implement the support?
https://github.com/reactjs/redux/blob/master/src/combineReducers.js#L47 in combineReducers is causing an issue as it does not recognize newly added form state keys
@clbond @SethDavenport @smithad15 @e-schultz
Especially the fix for broken reactive forms is absolutely important.
PR #42 is hanging around since september...
ngc
NodeJS Version: 6
Typescript Version: 2.2
Angular Version: 4
@angular-redux/store version: 6.2.0
I thought this would work with both reactive and template driven forms. When I set it up via a template driven forms it works. But when I try and add a reactive form to the page I get an error about "no provider for ngForms".
Is this going to/should support reactive forms?
<form [formGroup]="loginForm" connect="loginForm">
<div class="form-group">
<label class="center-block">Email</label>
<input class="form-control" formControlName="email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input show-password class="form-control" id="password" type="password" formControlName="password">
</div>
</form>
private createForm() {
this.loginForm = this.fb.group({
email: ['', Validators.required],
password: ['', Validators.required]
});
Instead of the template approach found in the sample app (feedback form).
Returns ERROR Error: Uncaught (in promise): Error: No provider for NgForm!
ngc
NodeJS Version: 8.1.1
Typescript Version: 2.3.4
Angular Version: 4.1.2
@angular-redux/store version: 7.1.1
@angular/cli version: (if applicable)
OS: OSX
(optional, but helps a lot)
Input field on change should update the corresponding value in the redux store.
Input field value doesn't change on keystroke, as it's bound to the store which is not updating.
Just need some help please. Any idea where the problem could be?
<form [connect]="['advertiser', 'campaign', 'campaign']">
<div class="input-container">
<input
ngControl
ngModel
class="form-control"
type="text"
name="name">
</div>
</form>
1: The input field shows the value coming from the redux store, so the path is good.
2: On keydown, I can see the action firing in the devtools, payload looks fine.
3. When I inspect State.assign
in state.js
, state
, path
, and value
arguments look fine but for some reason, the state doesn't get updated. Sorry I can't show repo, but maybe someone has any idea what I'm missing.
Thank you.
ngc
NodeJS Version: 7.8.0
Typescript Version: 2.2.2
Angular Version: 4.2.2
@angular-redux/store version: 6.4.5
@angular/cli version: 1.0.6
OS: mac os
https://github.com/artparks/forms-actions
Just one action to be fired when the forms are updated
Two actions are fired, one with the payload set correctly to the new state of the input, then immediately another one after this whose payload is the previous state.
n.a
I've replicated the setup shown in the example repo, but cannot prevent this issue. It seems that when the this.form.valueChanges
callback is fired in connect.ts
, the action published causes this observable to immediately fire again. If I remove the call to publish the action in the callback, it only fires once. I assume when the field is updated via NgModel this causes the second firing of the action. I cannot see why this is happening or how to prevent it, especially when this example is so similar to the example that does work.
I specified ng-model-options:
<input type="text" class="form-control" name="question1" ngControl ngModel ng-model-options="{ debounce : { default : 1500, blur : 0 } }"/>
but FORM_CHANGED action is dispatched on every keystroke.
ngc
NodeJS Version: 7.10.0
Typescript Version: 2.3.4
Angular Version: 4.3.4
@angular-redux/store version: 6.5.7
@angular/cli version: 1.2.6
OS: OSX 10.12.6
(optional, but helps a lot)
Using the module
Im trying to implement the module in my application but when I try to use:
<form [connect]="['level','detail']">
I got an console error like if the connect directive is not loaded
Can't bind to 'connect' since it isn't a known property of 'form'
### Stack Trace/Error Message:
### Additional Notes:
(optional)
Im defining a module for my component where Im loading the necessary modules:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgReduxModule } from '@angular-redux/store';
import {
NgReduxFormModule,
NgReduxFormConnectModule
} from '@angular-redux/form';
import { AnimalFormDialogComponent } from './animal-form.dialog.component';
import {
MdDialogModule
} from '@angular/material';
@NgModule({
declarations: [
AnimalFormDialogComponent
],
imports: [
CommonModule,
ReactiveFormsModule,
FormsModule,
NgReduxFormModule,
NgReduxModule,
NgReduxFormConnectModule,
MdDialogModule
],
providers: [],
exports: [AnimalFormDialogComponent]
})
export class AnimalFormDialogModule { }
ngc
NodeJS Version:
Typescript Version:
Angular Version:
@angular-redux/store version:
@angular/cli version: (if applicable)
OS:
(optional, but helps a lot)
I have used this library to connect a form input to my redux store. However, on the frontend I would like to apply an angular pipe to the input field that will format the entered integer into a comma-separated string (e.g. 10000 --> '10,000'). I would like my store to maintain the integer (10000) as the input's value, whereas the user will see the string '10,000'.
I tried applying a transformation to the payload (the formatted string), when '@@angular-redux/form/FORM_CHANGED' is triggered, to transform the formatted string from the input field into a simple integer. However, this resulted in an infinite loop of "FORM_CHANGED" actions being dispatched.
This is POC code that resolves the issue described.
ngAfterContentInit() {
Promise.resolve().then(() => {
this.resetState();
this.stateSubscription = this.store.subscribe(() => {
this.formChangedSoOmitNextChange = true; // SET TRUE HERE
this.resetState()
});
Promise.resolve().then(() => {
this.formSubscription = (<any>this.form.valueChanges)
.debounceTime(0)
.subscribe((values: any) => {
if (this.formChangedSoOmitNextChange) {
this.formChangedSoOmitNextChange = false; // SET FALSE HERE
} else this.publish(values)
});
});
});
}
Template code:
<input
class="form-control border-none"
name="chairs"
required
min="0"
[ngModel]="(woodshopState$ | async).data.chairs | number: '1.0-0' | numberHideZero"
>
FORM_CHANGED action handler code:
switch (action.type) {
case '@@angular-redux/form/FORM_CHANGED':
return <IWoodshopState>{
...state,
data: {
...state.data,
chairs: has('chairs', action.payload.value)
? toNumber(action.payload.value.chairs)
: state.data.chairs,
},
};
@angular/cli
ngc
NodeJS Version: 8.10
Typescript Version: ~2.5.3
Angular Version: 5
@angular-redux/store version: 7
@angular-redux/form version: 6.7
@angular/cli version: ~1.7.3
OS: Windows
How can I reset the form state?
I'm just added this
<form connect="name">
and <input ngModel ngControl ...>
And I want in component.ts after some action reset state of the form "name"?
NodeJS Version:
Typescript Version: ~4.0.2
Angular Version: 10.1.0
@angular-redux/store version: 10.0.0
@angular/cli version: 10.1.0
OS: MAC OS Mojave version 10.14.6
'formDirective' is defined as an accessor in class 'ControlContainer'
'path' is defined as an accessor in class 'ControlContainer', but is overridden here in 'ConnectArrayDirective' as an instance property.
@angular-redux/form": "^10.0.0",
"@angular-redux/router": "^10.0.0",
"@angular-redux/store": "^10.0.0",
"@angular/animations": "~10.1.0",
"@angular/common": "~10.1.0",
"@angular/compiler": "~10.1.0",
"@angular/core": "~10.1.0",
"@angular/forms": "~10.1.0",
node_modules/@angular-redux/form/connect-array/connect-array.directive.d.ts:22:14 - error TS2610: 'formDirective' is defined as an accessor in class 'ControlContainer', but is overridden here in 'ConnectArrayDirective' as an instance property.
22 readonly formDirective: FormGroupDirective;
~~~~~~~~~~~~~
node_modules/@angular-redux/form/connect-array/connect-array.directive.d.ts:23:14 - error TS2610: 'path' is defined as an accessor in class 'ControlContainer', but is overridden here in 'ConnectArrayDirective' as an instance property.
23 readonly path: string[];
Updated the angular 9 to 10
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"enableIvy": true
}
ngc
NodeJS Version: 6.9.2
Typescript Version: 2.4.2
Angular Version: 4.4.6
@angular-redux/store version: 6.6.0
@angular/cli version: (if applicable) 1.6.3
OS: Win 10
(optional, but helps a lot)
That directive work as expected at first time that the form is built and state on store reflect the form.
The state doesn't update when a form change occurss, also, no action is fired
No stack trace
Again, the directive only works when I open my form by the secont time
NodeJS Version: 6.10
Typescript Version: 2.3.0
Angular Version: 4.0.3
angular-redux/store version: 6.2.0
angular/cli version: 1.0.0-beta.32.3
OS: windows 10
Cannot read property 'arrivalTime' of undefined
The problematic areas are surrounded by comment ERROR HERE
<div class="form-panel">
<div class="steps-panel">
<div class="step" *ngFor="let step of steps; let i = index; let isLast = last" [ngClass]="{current: i + 1 == (addClientForm$ | async)?.currentPosition, pass: i + 1 < (addClientForm$ | async)?.currentPosition}">
<div class="circle-holder">
<div class="circle">
<span *ngIf="i + 1 >= (addClientForm$ | async)?.currentPosition">{{i + 1}}</span>
<md-icon *ngIf="i + 1 < (addClientForm$ | async)?.currentPosition">done</md-icon>
</div>
<div class="label">{{step}}</div>
</div>
<div *ngIf="!isLast" class="line"></div>
</div>
</div>
<ng-container [ngSwitch]="(addClientForm$ | async)?.currentPosition">
<form class="form" *ngSwitchCase="1" [connect]="['hqAddClientForm', 'clientDetails']">
<div class="regular-input-holder">
<div class="label">שם העסק</div>
<input type="text" name="businessName" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">מספר העסק</div>
<input type="text" name="businessNumber" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">כתובת</div>
<input type="text" name="address" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">טלפון</div>
<input type="text" name="phone" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">פקס</div>
<input type="text" name="fax" ngControl ngModel>
</div>
<div class="save-and-continue">
<button md-raised-button class="md-primary-button" (click)="saveContinue()">
<md-icon>done</md-icon>שמור והמשך
</button>
</div>
</form>
<form class="form" *ngSwitchCase="2" [connect]="['hqAddClientForm', 'paymentDetails']">
<div class="regular-input-holder">
<div class="label">אופן תשלום</div>
<input type="text" name="paymentMethod" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">אחוזי הנחה</div>
<input type="text" name="discountPercentage" ngControl ngModel>
</div>
<div class="save-and-continue">
<button md-raised-button class="md-primary-button" (click)="saveContinue()">
<md-icon>done</md-icon>שמור והמשך
</button>
</div>
</form>
<ng-container *ngSwitchCase="3">
<form class="form" [connect]="['hqAddClientForm', 'managers', 'tmp']">
<div class="regular-input-holder">
<div class="label">שם ושם משפחה</div>
<input type="text" name="firstAndLastName" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">אימייל</div>
<input type="email" name="email" ngControl ngModel>
</div>
<div class="regular-input-holder">
<div class="label">נייד</div>
<input type="phone" name="phone" ngControl ngModel>
</div>
<div class="save-and-continue">
<button md-raised-button class="md-primary-button" (click)="addManager()">
<md-icon>add</md-icon>הוספת מנהל
</button>
</div>
</form>
<div class="managers">
<div class="manager" *ngFor="let manager of (addClientForm$ | async)?.managers?.managers">
<div class="info">
<div class="full-name">{{manager.firstAndLastName}}</div>
<div class="phone-email">
<span>{{manager.phone}}</span>
<span>{{manager.email}}</span>
</div>
</div>
<md-icon class="edit">edit</md-icon>
</div>
</div>
<div class="save-and-continue">
<button md-raised-button class="md-primary-button" (click)="saveContinue()">
<md-icon>done</md-icon>שמור והמשך
</button>
</div>
</ng-container>
<div class="system-type form" *ngSwitchCase="4">
<div class="switch-buttons">
<div class="button-option" [ngClass]="{clicked: (addClientForm$ | async)?.clientSystemType?.type === 'shifts'}" (click)="toggleSystemType()">משמרות</div>
<div class="button-option" [ngClass]="{clicked: (addClientForm$ | async)?.clientSystemType?.type === 'general'}" (click)="toggleSystemType()">כללי</div>
</div>
<form *ngIf="(addClientForm$ | async)?.clientSystemType?.type === 'general'" class="form" [connect]="['hqAddClientForm', 'clientSystemType', 'general']">
<div class="regular-input-holder">
<div class="label">סוג לוח</div>
<input type="text" name="calendarType" ngControl ngModel>
</div>
</form>
<form *ngIf="(addClientForm$ | async)?.clientSystemType?.type === 'shifts'" class="form" [connect]="['hqAddClientForm', 'clientSystemType', 'shiftsType']">
<!-- ERROR HERE -->
<ng-template connectArray let-index connectArrayOf="shifts">
<div class="regular-input-holder" [ngModelGroup]="index">
<div class="header">משמרת {{index + 1}}</div>
<select ngControl ngModel name="arrivalTime">
<option *ngFor="let num of times" [value]="num">{{num}}</option>
</select>
<select ngControl ngModel name="departureTime">
<option *ngFor="let num of times" [value]="num">{{num}}</option>
</select>
</div>
</ng-template>
<!-- END ERROR HERE -->
</form>
<div class="save-and-continue">
<button md-raised-button class="md-primary-button" (click)="saveContinue()">
<md-icon>done</md-icon>שמור והמשך
</button>
</div>
</div>
</ng-container>
</div>
The rest of the forms are working fine
export interface HQAddClientForm {
currentPosition: number,
clientDetails: {
businessName: string,
businessNumber: number,
// belongsTo: string,
// businessType: string,
address: string,
phone: string,
fax: string,
},
paymentDetails: {
paymentMethod: string,
discountPercentage: number
},
managers: {
tmp: HQClientManager,
managers: HQClientManager[]
},
clientSystemType: {
type: 'general' | 'shifts',
generalType: {
calendarType: string
},
// --- ERROR HERE ---
shiftsType: {
numberOfShifts: number,
shifts: {
arrivalTime: string,
departureTime: string
}[]
}
// --- END ERROR HERE ---
},
routes: {
tmp: HQClientRoute,
routes: HQClientRoute[]
}
}
export interface HQClientManager {
firstAndLastName: string,
email: string,
phone: string
}
export interface HQClientRoute {
origin: string[],
destination: string[],
totalKM: number,
permanentDriver: {
driverKey: string,
name: string
},
priceExpiritionDate: string,
driverPayment: {
amount: number,
incluedTax: boolean
},
totalPayment: {
amount: number,
incluedTax: boolean
}
}
export const initHQAddClientForm: HQAddClientForm = {
currentPosition: 1,
clientDetails: {
businessName: null,
businessNumber: null,
// belongsTo: null,
// businessType: null,
address: null,
phone: null,
fax: null,
},
paymentDetails: {
paymentMethod: null,
discountPercentage: null
},
managers: {
tmp: {
firstAndLastName: null,
email: null,
phone: null
},
managers: []
},
clientSystemType: {
type: 'shifts',
generalType: {
calendarType: null
},
// --- ERROR HERE ---
shiftsType: {
numberOfShifts: null,
shifts: [{
arrivalTime: null,
departureTime: null
}]
}
// --- END ERROR HERE ---
},
routes: {
tmp: {
origin: [],
destination: [],
totalKM: 0,
permanentDriver: {
driverKey: null,
name: null
},
priceExpiritionDate: null,
driverPayment: {
amount: 0,
incluedTax: null
},
totalPayment: {
amount: 0,
incluedTax: null
}
},
routes: []
}
}
core.es5.js:1084 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'arrivalTime' of undefined
TypeError: Cannot read property 'arrivalTime' of undefined
at http://localhost:4200/vendor.bundle.js:30431:22
at http://localhost:4200/vendor.bundle.js:30356:66
at Array.forEach (native)
at FormGroup._forEachChild (http://localhost:4200/vendor.bundle.js:30356:36)
at FormGroup._checkAllValuesPresent (http://localhost:4200/vendor.bundle.js:30430:14)
at FormGroup.setValue (http://localhost:4200/vendor.bundle.js:30237:14)
at http://localhost:4200/vendor.bundle.js:30936:18
at ZoneDelegate.invoke (http://localhost:4200/vendor.bundle.js:156556:26)
at Object.onInvoke (http://localhost:4200/vendor.bundle.js:8978:37)
at ZoneDelegate.invoke (http://localhost:4200/vendor.bundle.js:156555:32)
at http://localhost:4200/vendor.bundle.js:30431:22
at http://localhost:4200/vendor.bundle.js:30356:66
at Array.forEach (native)
at FormGroup._forEachChild (http://localhost:4200/vendor.bundle.js:30356:36)
at FormGroup._checkAllValuesPresent (http://localhost:4200/vendor.bundle.js:30430:14)
at FormGroup.setValue (http://localhost:4200/vendor.bundle.js:30237:14)
at http://localhost:4200/vendor.bundle.js:30936:18
at ZoneDelegate.invoke (http://localhost:4200/vendor.bundle.js:156556:26)
at Object.onInvoke (http://localhost:4200/vendor.bundle.js:8978:37)
at ZoneDelegate.invoke (http://localhost:4200/vendor.bundle.js:156555:32)
at resolvePromise (http://localhost:4200/vendor.bundle.js:156934:31)
at http://localhost:4200/vendor.bundle.js:156985:17
at ZoneDelegate.invokeTask (http://localhost:4200/vendor.bundle.js:156589:31)
at Object.onInvokeTask (http://localhost:4200/vendor.bundle.js:8969:37)
at ZoneDelegate.invokeTask (http://localhost:4200/vendor.bundle.js:156588:36)
at Zone.runTask (http://localhost:4200/vendor.bundle.js:156356:47)
at drainMicroTaskQueue (http://localhost:4200/vendor.bundle.js:156749:35)
at <anonymous>
When I change the value in the problematic (with name "arrivalTime"), I see change in my store, but it creates a new object 0 in shiftType. perhaps the ref tree isn't right, but I checked it multiple times and seems it is like writing in the docs. Thanks
When installing as a dependency of https://github.com/angular-redux/example-app I get the following error.
npm ERR! @angular-redux/[email protected] postinstall: npm run build
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @angular-redux/[email protected] postinstall script 'npm run build'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the @angular-redux/form package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! npm run build
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs @angular-redux/form
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls @angular-redux/form
npm ERR! There is likely additional logging output above.
applies to angular-redux/example-app#13
ngc
NodeJS Version: 8.0.0
Typescript Version: 2.2.2
Angular Version: 4.1.3
@angular-redux/store version: 6.4.3
@angular/cli version: 1.0.6
OS: OS X
Programs with TypeScript's strictNullChecks
enabled should compile to JavaScript
TypeScript gets angry about null
s since they're no longer automagically unioned with every type in strictNullChecks
mode
ERROR in ~/node_modules/@angular-redux/form/source/state.ts (79,32): Argument of type 'null' is not assignable to parameter of type 'string | number'.
ERROR ~/node_modules/@angular-redux/form/source/state.ts (100,39): Argument of type 'null' is not assignable to parameter of type 'string | number'.
ERROR in ~/node_modules/@angular-redux/form/source/compose-reducers.ts (15,7): Type 'null' is not assignable to type 'State'.
ERROR in ~/node_modules/@angular-redux/form/source/compose-reducers.ts (27,42): Argument of type 'null' is not assignable to parameter of type 'string | number'.
ERROR in ~/node_modules/@angular-redux/form/source/form-reducer.ts (19,20): Type 'Keyed<string, any> | RootState | undefined' is not assignable to type 'Keyed<string, any> | RootState'.
Type 'undefined' is not assignable to type 'Keyed<string, any> | RootState'.
ERROR in ~/node_modules/@angular-redux/form/source/shims.ts (13,14): Type 'string[] | null' is not an array type.
ERROR in ~/node_modules/@angular-redux/form/source/shims.ts (18,24): Type 'null' is not assignable to type 'ControlValueAccessor'.
ERROR in ~/node_modules/@angular-redux/form/source/shims.ts (42,7): Variable 'customAccessor' is used before being assigned.
ERROR in ~/node_modules/@angular-redux/form/source/shims.ts (43,7): Variable 'builtinAccessor' is used before being assigned.
ERROR in ~/node_modules/@angular-redux/form/source/shims.ts (44,7): Variable 'defaultAccessor' is used before being assigned.
ERROR in ~/node_modules/@angular-redux/form/source/connect-array.ts (120,5): Type 'ValidatorFn | null' is not assignable to type 'ValidatorFn'.
Type 'null' is not assignable to type 'ValidatorFn'.
ERROR in ~/node_modules/@angular-redux/form/source/connect-array.ts (124,5): Type 'AsyncValidatorFn | null' is not assignable to type 'AsyncValidatorFn'.
Type 'null' is not assignable to type 'AsyncValidatorFn'.
Took me a while to figure out how to get actions flowing from my form. The README.md could be improved with a quick angular-redux/store example, including:
Connect
, FormStore
defaultReducer
being attached to the storeprovideStore
.Right now the info is all there but it's a bit scattered.
"@angular-redux/form": "^6.7.0",
"@angular-redux/store": "^7.1.0",
"@angular/animations": "^5.2.4",
"@angular/cdk": "^5.2.1",
"@angular/common": "^5.2.4",
"@angular/compiler": "^5.2.4",
"@angular/core": "^5.2.4",
"@angular/forms": "^5.2.4",
"@angular/http": "^5.2.4",
"@angular/material": "^5.2.1",
"@angular/platform-browser": "^5.2.4",
"@angular/platform-browser-dynamic": "^5.2.4",
"@angular/router": "^5.2.4",
"@angular/cli": "^1.6.8",
"@angular/compiler-cli": "^5.2.4",
Get error message
ERROR Error: StaticInjectorError(AppModule)[ConnectArray -> ConnectBase]: StaticInjectorError(Platform: core)[ConnectArray -> ConnectBase]: NullInjectorError: No provider for ConnectBase!
when using Angular 5
Similar with to issue.
ngrx/platform#549
Tests recently started failing with this stack trace:
yarn test
:
ERROR in ./source/tests.entry.ts
Module build failed: TypeError: Cannot set property 'babelOptions' of undefined
at Object.ngcLoader (/Users/sdavenpo/code/angular-redux/ng2-redux-form/node_modules/@ngtools/webpack/src/loader.js:200:34)
28 01 2017 22:45:11.188:ERROR [karma]: { Error: no such file or directory
at MemoryFileSystem.readFileSync (/Users/sdavenpo/code/angular-redux/ng2-redux-form/node_modules/memory-fs/lib/MemoryFileSystem.js:107:10)
at MemoryFileSystem.(anonymous function) [as readFile] (/Users/sdavenpo/code/angular-redux/ng2-redux-form/node_modules/memory-fs/lib/MemoryFileSystem.js:300:34)
at doRead (/Users/sdavenpo/code/angular-redux/ng2-redux-form/node_modules/karma-webpack/lib/karma-webpack.js:201:29)
at Plugin.readFile (/Users/sdavenpo/code/angular-redux/ng2-redux-form/node_modules/karma-webpack/lib/karma-webpack.js:205:5)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
code: 'ENOENT',
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.