0

I am getting the following response from a service, which includes form definition in json schema format.

Json response

Now I want to iterate this response in angular component.

So I have fetched all the schema elements like this in one Formdata variable.

          res['tabs'].forEach(element => {
              this.tablist.push(element);

            });


       this.tablist.forEach(element => {

            this.FormData[element] = res['com'][element]['schema'];
            this.FormValueData[element] = res['com'][element]['data'];
            this.FetchValueParam[element] = res['com'][element]['data'];
        });

Now I want to access the value of Formdata in side a view and I have wrote following code for it.

                  <form>
                      <div *ngFor='let input1 of FormData[element]['properties']'>

                        <label [for]='input1.type'> input1.title</label>
                        <input type='input1.type' [name]='input1.title' 
                       [placeholder]='something'>
                        <br>
                      </div>
                      <br><br>
                      <button type="submit"> Submit </button>



                   </form> 

But I am not able to access this it as an array as it is a json object. I have tried Array.of() and Array.from() but it is not working with the following error. How to iterate through the json and create form fields?

            Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays

Update: When I am using a dummy json object like this. I am getting desired result. So what I am getting is , there is some serious mismatch between type expected by ngFor and type I am supplying as a json object.

               this.inputfield=
             [{type:'email',name:'email',value:'',placeholder:"your email here"},
            {type:'email',name:'email',value:'',placeholder:'your email 
               here'},{type:'email',name:'email',value:'',placeholder:'your 
                 email here'},
            {type:'email',name:'email',value:'',placeholder:'your email 
                here'},{type:'email',name:'email',value:'',placeholder:'your 
              email here'},
             {type:'email',name:'email',value:'',placeholder:'your email 
               here'},{type:'email',name:'email',value:'',placeholder:'your 
             email here'},
             {type:'email',name:'email',value:'',placeholder:'your email 
             here'},{type:'email',name:'email',value:'',placeholder:'your 
             email 
             here'}{type:'email',name:'email',value:'',placeholder:'your 
              email here'}]; 

When I checked the difference between both of them in json schema validator, The Former I showed in console is coming as object but the above is coming is array.

So Either I send array not object or I create one array or class based on above json schema at run time. What is better to do?

Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84

1 Answers1

1

Assuming that this.tablist is an array of strings you can change the object being created in this.FormData[element] to an array:

    this.tablist.forEach(element => {
        Object.keys(res['com'][element]['schema']['properties']).forEach(inputKey => {
            this.FormData[element] = [];
            this.FormData[element].push(res['com'][element]['schema']['properties'][inputKey]);
        }
        this.FormValueData[element] = res['com'][element]['data'];
        this.FetchValueParam[element] = res['com'][element]['data'];
    });

And then use it in the template as shown below.

<div *ngFor='let input1 of FormData[element]'>

Also, you are not using property binding right on this line(that is if you don't have a variable named something in the component):

[placeholder]='something'>.

It should be

[placeholder]='"something"'>

Victor Luchian
  • 112
  • 1
  • 10
  • when I apply above changes. console says "_this.FormData[element].properties.push is not a function" – Talk is Cheap Show me Code Feb 13 '18 at 05:23
  • you can declare it below the forEach function: `this.FormData[element]['properties'] = []` – Victor Luchian Feb 13 '18 at 08:48
  • When I tried this this.FormData[element]['properties'] = []; it says can not set 'properties' on undefined. When I remove the [element] and just accessed the data in this.FormData['properties'] it worked. but I need to have identified for [element] . what I am missing? – Talk is Cheap Show me Code Feb 13 '18 at 09:23
  • I am really one step away from what I am trying to achieve. I really don't know why when I did as per your suggestion this.FormData[element]['properties'] = []; it is showing the error that "can not set 'properties' on undefined" element here is defined and I am able to get it in console. – Talk is Cheap Show me Code Feb 13 '18 at 09:56
  • I'm glad, can you please mark my answer as correct? – Victor Luchian Feb 14 '18 at 12:37
  • This has solved many of my probs. I need not to convert the json object in type script class. This array will do my work. – Talk is Cheap Show me Code Feb 14 '18 at 12:47
  • One more thing I am stuck with this is, How to use this form elements in two way data binding? I need to create either template driven or reactive form , I am confused between both of them that which one is good to use in this situation? – Talk is Cheap Show me Code Feb 15 '18 at 05:47
  • I think in your case you can use template driven forms and using [(ngModel)] you can obtain the two-way data binding – Victor Luchian Feb 15 '18 at 10:53
  • Hi Victor, Thanks for your suggestion. I was not able to create such large number of variables in .ts files So I have used the below syntax and got the values of all fields in custom_submit function :
    . So My question is if I do the same thing for on change event of form ? can I still have all flexibility to apply conditional validations and on field change events without binding a single input. Because the array I am getting has all the values and input keys.
    – Talk is Cheap Show me Code Feb 15 '18 at 13:51