ngneat / forms-manager Goto Github PK
View Code? Open in Web Editor NEW๐ฆ The Foundation for Proper Form Management in Angular
Home Page: https://www.netbasal.com
License: MIT License
๐ฆ The Foundation for Proper Form Management in Angular
Home Page: https://www.netbasal.com
License: MIT License
I'm thinking about adding a new observable
which notifies whether the form is dirty
. Dirty means that the current value is different from the initial value.
This observable can be used to toggle the visibility of a save
button:
isDirty$ = this.manager.selectIsDirty(formName);
<button *ngIf="isDirty$ | async">Save</button>
Or show a dialog when the user leaves the page.
We need to think whether it makes sense that it'll work in conjunction with the persist form feature.
[ ] 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
[ ] Other... Please describe:
When using updateOn:'blur'
on a form field, if I type something in the field and click submit button directly without tabbing out the input or clicking outside of it, the value using this.manager.getControl('stepOne','textarea').value
is not available strait away, it needs a timeout.
Should have the value available immediately.
Please see the stackblitz example check the console logs when pressing submit. stackblitz edit example
Angular version: X.Y.Z
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
Cannot get the initial value of form. This was in private.
We would like to be able to obtain the initial value of the form. This value has been saved by the plug-in for the isDirty function.
It is not possible to retrieve this value, as it is in private property. There is a method called setInitialValue(). It would be useful to have a method: getInitialValue().
/**
*
*/
getInitialValue(name: keyof FormsState): any {
return this.initialValues$$.get(name);
}
In our case, we would need to retrieve the initial value of the form, in order to make calculations afterwards to calculate the differences and track all the changes that have been made. And, like, we would use this plug-in that would store the initial state. It would be a shame to have to store this state somewhere else, when it's already stored in form-manager, and we could just retrieve it here.
Is it ok for you to make a pull request to add this feature to the plug-in?
[ ] 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
[ ] Other... Please describe:
show Ivy warning when build with an ivy project
"Encourage the library authors to publish an Ivy distribution"
support Ivy
use forms-manager in a new angular13+ project
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ x] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I have a project with akita and the forms-manager. I feel like I'm using it fairly simply, but there is a noticeable roughly 1 second lag between patching a value and seeing the change manifest down through the .valueChanges observable. Attached code and behavior video below. No clue what I could be doing to see such an issue in performance.
Angular version: 9.1.2
Browser:
- [ x] Chrome (desktop) version 86
- [ ] 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
####Nested component:
Screen Recording 2020-10-20 at 9.04.58 PM.mov.zip
When calling the methods formsManager.clear()
or formsManager.destroy()
without parameters the existing initial values are not being cleared.
Calling formsManager.clear()
or formsManager.destroy()
should also clear the Map
of the initial values (initialValues$$
).
So you don't have to call removeInitialValue(name)
(is actually private) for each set initial value.
This module supported a custom storage provider when it was part of Akita. Now, it appears only to support localStorage. Limitations of localStorage are well known and it would be nice if the old functionality was brought back so that the state could be saved to things like IndexedDB or similar. This is specially vital for things like hybrid apps where webview storage may be purged by the OS and the only way to ensure persistence of the data is to save it to SQLite or similar. Support for a custom storage provider or at least IndexedDB would be nice. Thanks
This is a really helpful tool, thank you.
I use Kendo to handle date pickers and Kendo expects a Date() object for FormControl values:
this.mainForm = this.fb.group({
searchEndDate: [new Date(), Validators.required],
});
With the above, I get a Date() that Kendo consumes.
When I connect the Forms Manager,
this.formsManager.upsert(this.formManagerKey, this.mainForm, {
persistState: true
});
Now 'searchEndDate' is a string
When I add the forms Manager, the date gets converted to a string. Is there a way to get the Forms Manager to maintain the type of the date as a Date()?
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[x] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
I am currently using the last version of Akita Store.
I tried to install and use this package as stated on the README file but i got the following error.
No provider for NgFormManager.
So i added the NgFormManager as a provider in my AppModule. The error disappeared but nothing else happened.
What steps am I missing ?
I saw the package lock is saying the package was made with Angular 9.
Can it still work for Angular 8 application ?
The package work as stated in the README file
Install and use the code from the Installation
section of the README file.
Can have the advantage of forms in Akita Store.
Angular version: 8 (core: 8.2.14)
Browser:
- [x] Chrome (desktop) version 85
- [ ] 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.16.3
- Platform: macOS 10.14.6
Others:
None
[ ] 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
[ ] Other... Please describe:
Using a mat date picker the value is an empty object instead of the date selected.
The correct date to be stored instead of an empty object.
Add a mat date picker and persist to local storage.
To have the date persist on refresh.
Angular version: 9.1.9
Browser:
- [X] Chrome (desktop) version 81.0.4044.138
- [ ] 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: 12.16.3
- Platform: Windows
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[x] Support request
[ ] Other... Please describe:
When upsert is used to replace firstForm FormGroup on 'example' key with a new secondForm FormGroup on 'example' key the store does not take the values from the new secondForm control it instead copies over the values from the old firstForm control into the secondForm control replacing the it's values.
firstForm = new FormGroup({
id: new FormControl("123")
});
secondForm = new FormGroup({
id: new FormControl("456")
});
this.manager.upsert("example", this.firstForm);
// this.manager.getControl("example").value = {"id":"123"}
this.manager.upsert("example", this.secondForm);
// this.manager.getControl("example").value = {"id":"123"} <--- old value
Relevant section of the codebase
Work around at the moment is to perform a clear on the 'example' key, removing the old form group so that when the new one is passed in it wont have an existing FormGroup at the 'example' key to copy data from.
this.manager.upsert("example", this.firstForm);
// this.manager.getControl("example").value = {"id":"123"}
this.manager.clear("example");
this.manager.upsert("example", this.secondForm);
// this.manager.getControl("example").value = {"id":"456"} <--- new value
The secondForm values replace the store values.
https://stackblitz.com/edit/github-mt9mwh?file=src/app/example.component.ts
It feels counterintuitive that an upsert method would change the values on the FormGroup being passed in to match the store. I'm aware this may in fact be me miss using this feature so any clarification would be appreciated.
https://stackblitz.com/edit/github-mt9mwh?file=src/app/example.component.ts
Angular version: 9.1.13
Browser:
instead of persist form, how to persist only some controls, please
Would it make sense to add support the mark*()
methods for a form or a control?
The methods could be called like formsManager.patchValue()
:
formsManager.markAllAsTouched('unboarding')
formsManager.markAsDirty('unboarding')
formsManager.markAsPending('unboarding')
formsManager.markAsPristine('unboarding')
formsManager.markAsTouched('unboarding')
formsManager.markAsUntouched('unboarding')
[ ] 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
[ ] Other... Please describe:
this.formsManager
.upsert('skills', this.skills, { arrControlFactory: value => new FormGroup(value) })
);
ERROR TypeError: control.setParent is not a function
at forms.js:4112
at forms.js:4106
at Array.forEach (<anonymous>)
at FormGroup._forEachChild (forms.js:4101)
at FormGroup._setUpControls (forms.js:4111)
at new FormGroup (forms.js:3833)
at arrControlFactory (ubo-form.component.ts:23)
at ngneat-forms-manager.js:393
at Array.forEach (<anonymous>)
at handleFormArray (ngneat-forms-manager.js:388)
That I can track an array of FormGroup's.
Have the ability to add an array of skills, where a skill is a name + proficiency.
Hey!
thanks for this great library!
Is is possible to retrieve the saved values of a form in a different component? Basically I'm working on wizard and I need to calculate some values based on prior responses (1 wizard page with a single form = 1 component).
Thanks in advance.
Regards
ml
Currently, when we use the path
parameter in the selectValue
, and selectControl
methods, we need to pass a generic that indicates what should be the type of the value
property:
selectValue<string>('login', 'name');
This isn't the end of the world, but we can employ the technique used in this question to infer it automatically. So the expected usage should be:
selectValue('login', 'name');
selectValue('group', ['some', 'nested', 'control']);
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[X ] Support request
[ ] Other... Please describe:
Unable to make a valueChanges reaction to work in a unit test
A subscription to valueChanges should work in unit tests too (but maybe I'm missing something).
The only other non-default dependency is Specator. Simply run npm test to see it failing.
// ### app.component.ts
interface AppForms {
myForm: {
theInput: string;
};
}
@Component({
selector: 'app-root',
template: `<form [formGroup]="form"><input type="text" formControlName="theInput" /></form> `,
styles: [],
})
export class AppComponent implements OnInit, OnDestroy {
private formKey: 'myForm';
form: FormGroup;
constructor(
private formsManager: NgFormsManager<AppForms>,
private fb: FormBuilder
) {}
ngOnInit(): void {
this.form = this.fb.group({
theInput: [null],
});
this.formsManager.upsert(this.formKey, this.form);
// This makes the test go green
// this.form
// .get('theInput')
// .valueChanges.pipe(filter((value) => value != null))
// .subscribe(this.valueSetter);
this.formsManager
.valueChanges(this.formKey, 'theInput')
.pipe(filter((value) => value != null))
.subscribe(this.valueSetter);
}
private valueSetter = (value) =>
this.form.get('theInput').setValue(value + 'Append', { emitEvent: false });
ngOnDestroy(): void {
this.formsManager.destroy(this.formKey);
}
}
// ### app.component.spec.ts
describe('AppComponent', () => {
let spectator: Spectator<AppComponent>;
const createComponent = createComponentFactory({
component: AppComponent,
imports: [ReactiveFormsModule]
});
beforeEach(() => (spectator = createComponent()));
it(`should update the value of the input field`, () => {
const value = 'someText';
spectator.typeInElement(value, 'input');
const actual = spectator.component.form.controls.theInput.value;
expect(actual).toEqual(value + 'Append');
});
});
Angular version: 9.1.11
and it fails with version 10.0.2 too
Browser:
- [x ] Chrome (desktop) version 83.0.4103.116
- [ ] 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.16.0
- Platform: Linux
Others:
age: [null, Validators.required]), ---> next parentheses need to be removed
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.