Code Monkey home page Code Monkey logo

Comments (6)

anasofiapaixao avatar anasofiapaixao commented on August 17, 2024 4

I managed to get a workaround working using the form's (onChanges) event callback. onChanges is very trigger happy (upon initializing a form with data I counted it being invoked 35 times) and for some reason is sometimes called with an empty JSON, but when the event object is not empty and aside from being called in spite of no changes, it is very reliable in the sense that it does catch every change. This workaround as is does not work with onChange inside an array, since lodash's get() understands aField[1].value but does not understand what aField[].value means. Since I don't need it, I didn't go through the trouble. This could actually be implemented without lodash's _.get() as long as your json is shallow.

I import lodash's get:

import get from 'lodash/get.js';

onChanges does not give me the object before the change, so I am keeping track of that myself:

  lastChange: any = {};

I am recursively traversing the form JSON looking for onChange callbacks, and saving them in a map structured like { formItemKey: callback }:


  onChanges: any = {};

  populateForm: Function = (entity: any) => {
      this.entity = entity;
      this.lastChange = entity;

      if (this.form) {
        // recursively traverse the form json
        let traverse = item => {
          if (item.items) {
            item.items.map(traverse);
          } else if (item.tabs) {
            item.tabs.map(traverse);
          }

          // keep track of onChange callbacks
          if(item.onChange) {
            this.onChanges[item.key] = item.onChange;
          }
        };
        this.form.map(traverse);
      }
  };

  ngOnInit() {
   ...
    this.populateForm(this.entity);
  }

Then in my onFormChange() callback I find opportunities for early exit, checking if:

  • the JSON is not empty (this happens half the time!)
  • if the fields we have onChange callbacks for have actually been changed (no changes happens almost the other half the time)

Then, because all my onChange callbacks return promises, I am using Promise.all so I can perform a redraw after everything is done, because my onChanges are updating a select's titleMap:


  onFormChange(entity: any) {
    let onChangesToCall = [];
    // asf's (onChanges) is very trigger happy and often is invoked with a fake empty
    // object, so ignore it
    if(Object.keys(entity).length === 0 && entity.constructor === Object) {
      return;
    }

    for (let [key, onChange] of Object.entries(this.onChanges)){
      if(get(entity, key) === get(this.lastChange, key)) {
        // no changes, no need to invoke onChange
        continue;
      }

      // check needed so typescript won't complain when compiling
      if(typeof onChange === 'function') {
        onChangesToCall.push(onChange(get(entity, key)));
      }
    }

    if(onChangesToCall.length <= 0) {
      return;
    }

    Promise.all(onChangesToCall)
        .then(() => 
            // redraw
            this.entityForm.initializeForm()
        )
        .catch(error => {
          ...
        });

    this.lastChange = entity;
  }

If you do not need promises, or do not need to perform anything after all onChanges are resolved (such as a redraw), you could very well just omit creating an onChangesToCall array at all.

Finally, I link the callback in the html:

	<json-schema-form
          ...
	  (onChanges)="onFormChange($event)">
	</json-schema-form>

While far from ideal, especially in terms of performance, it does work.

from ajsf.

dbuddha avatar dbuddha commented on August 17, 2024

Same issue here.
Is there a workaround?

from ajsf.

dbuddha avatar dbuddha commented on August 17, 2024

Nice workarround @anasofiapaixao,

Boa continuação / Keep it going :)

from ajsf.

lapastina avatar lapastina commented on August 17, 2024

Hi @anasofiapaixao,

Would it be possible for you to publish a complete example on the site "stackblitz.com"?

Thank you very much in advance.

from ajsf.

samudiogo avatar samudiogo commented on August 17, 2024

Thanks @anasofiapaixao ! your approach was the best fit on my solution!
and @lapastina follow below my example based at @anasofiapaixao code:

https://stackblitz.com/edit/angular-json-schema-form-dynamic-select-data-form-demo

from ajsf.

github-actions avatar github-actions commented on August 17, 2024

Stale issue

from ajsf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.