Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get component instance from field onInit event #946

Closed
Constantinos-Impact opened this issue May 12, 2018 · 9 comments
Closed

Get component instance from field onInit event #946

Constantinos-Impact opened this issue May 12, 2018 · 9 comments
Labels

Comments

@Constantinos-Impact
Copy link

I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ x] support request

Hello there, first thank you all for the great library.
I have one question. Is there a way to get component instance from on init event? Basically i am trying to create Cascaded Select like the example but without settings the field.to.options. I have implement a custom select wrapper using another select component lib and on the init function subscribing to other select valueChanges and change the url of the select component and reload it to fetch the new data.

Here is the part of code to get the idea.

  lifecycle: {

          onInit: (form, field) => {

            let selectComponent = field.component as SelectComponent;

            form.get('customerId').valueChanges.pipe(

              takeUntil(this.onDestroy$),
              startWith(form.get('customerId').value),
              tap(customerId => {

                if (!customerId) return;

                field.formControl.setValue('');
                field.templateOptions.config = this.selectConfig.getCustomerAccountConfig(customerId);

               selectComponent.loadFromUrl();

              }),
            ).subscribe();
          },
        }

Is what trying to do doable? the field.component as i can see is a function not the action component instance.

@aitboudad
Copy link
Member

aitboudad commented May 13, 2018

you can do it by assigning the component instance to field during component construction:

@Component({
  ...
})
export class SelectComponent extends FieldType implement OnDestroy {
  private _field: FormlyFieldConfig;
  set field(field) {
    this._field = field;
    this._field.templateOptions.componentRef = this;
  }
  get field() { return this._field; }
  ...
  ngOnDestroy() {
    if (this.field && this.field.templateOptions.componentRef) {
      delete this.field.templateOptions.componentRef;
    }
  }
}

IMO using a separate service would be better ;).

@Constantinos-Impact
Copy link
Author

Thanks @aitboudad. It worked like a charm :)

@aitboudad
Copy link
Member

Update: added ngOnDestroy to clear assigned componentRef.

@smile2014
Copy link

FormlyForm.html:2 ERROR TypeError: this.interceptTable is not a function
at eval (eval at _loop_1 (apes-form.component.ts:132), :5:6)
at FormlyField.push../node_modules/@ngx-formly/core/esm5/ngx-formly-core.js.FormlyField.lifeCycleHooks (ngx-formly-core.js:1056)
at FormlyField.push../node_modules/@ngx-formly/core/esm5/ngx-formly-core.js.FormlyField.ngOnInit (ngx-formly-core.js:1003)
at checkAndUpdateDirectiveInline (core.js:10097)
at checkAndUpdateNodeInline (core.js:11363)
at checkAndUpdateNode (core.js:11325)
at debugCheckAndUpdateNode (core.js:11962)
at debugCheckDirectivesFn (core.js:11922)
at Object.eval [as updateDirectives] (FormlyForm.html:2)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:11914)

@smile2014
Copy link

} else if (t === 'object') {
for (let k in metadata) {
let value = metadata[k];
if (type(value) === 'string') {
if (k === 'onInit' || k === 'onChanges' || k === 'doCheck'
|| k === 'afterContentInit' || k === 'afterContentChecked'
|| k === 'afterViewInit' || k === 'afterViewChecked'
|| k === 'onDestroy'
) {
metadata[k] = new Function('form, field', String(value));
} else if (k === 'onDepends') {
let functionBody = this.createOnDependsFunctionBody(value || undefined);
if (exists(functionBody)) {
metadata.lifecycle.onInit = new Function('form, field', functionBody);
}
}

@smile2014
Copy link

@aitboudad

@mrigank-taxak
Copy link

How to use lifecycle hooks in JSON-Schema in order to populate the options in the second selection field (backend API data) after the selection of the first field using the IDs.

@aitboudad
Copy link
Member

@mrigank-taxak see #1982 (comment)

@smile2014
Copy link

@aitboudad In the latest version, this is no longer necessary. Could you please clarify what to replace it with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants