-
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
Current Approach
At the moment when using a field that needs to mutate the dataset on save for example the ImageComponent needing to execute a file upload and set the value to the uploaded URL, the component itself pushes its save method into a service. This method is then called when save is triggered. The save method edits the control's value to the exit value.
This approach has a number of problems:
- The form builder component that created the field needs to be alive when save is triggered. This isn't always the case, the page builder creates multiple form builder instances.
- We're editing the value of the control not the save object. This means value changes triggers multiple times during the save process.
current ImageComponent save method
save(moduleId: string, documentId: string) {
if (this.value) {
if (
this.imageUrl.value &&
this.imageUrl.value !== this.value.name
) {
return of(this.imageUrl.value).pipe(
tap(() => this.cData.control.setValue(this.imageUrl.value))
);
} else {
const name = this.cData.preserveFileName ? this.value.name : [
moduleId,
documentId,
random.string()
].join('-') +
/**
* TODO:
* Maybe we should put a type extension based on type
* instead of taking from the name
*/
(this.value.name.split('.')[1]);
return from(
this.storage.upload(name, this.value, {
contentType: this.value.type,
customMetadata: {
moduleId,
documentId,
...(this.cData.generatedImages &&
formatGeneratedImages(this.cData.generatedImages))
}
})
).pipe(
switchMap((res: any) => res.ref.getDownloadURL()),
tap(url => this.cData.control.setValue(url))
);
}
} else {
this.cData.control.setValue(this.imageUrl.value);
return of({});
}
}Desired Approach
- All of the properties that need to be mutated during saving need to be accumulated when the form is created along with data pointers.
- Each such component needs to provide a self-sufficient method (meaning it doesn't depend on anything in the angular component) separate from the component itself.
- This method receives as arguments the initial value, current value, configuration from the definitions, moduleId, documentId and should return the final value.
- When save is triggered all of these methods are called in parallel.
- Once they all complete successfully the final object is mutated using the pointers collected initially.
- These methods aren't even called if the initial and current value don't differ
example save method
export function ImageSave(
initial: string,
current: any,
configuration: any,
moduleId: string,
documentId: string
) {
return from(
this.storage.upload(current.name, current.value, {
contentType: current.type,
customMetadata: {
moduleId,
documentId,
...(configuration.generatedImages &&
formatGeneratedImages(configuration.generatedImages))
}
})
).pipe(
switchMap((res: any) => res.ref.getDownloadURL())
);
}Note: We still need to properly define this.
Reactions are currently unavailable