4

I have created a Angular 2 service which reads a local json using http (could be rest service call later) and returns an Observable.

   @Injectable()
   export class WorkflowDataService {
   constructor(private http: Http) { }
   getProcessTemplates(): Observable<Response> {
       return this.http.get("/assets/jsons/process-templates.json");
   }}

the json that is being read looks like this

{
"process-templates": [
    {
        "name": "ABC",
        "desc": "ABC"
    },
    {
        "name": "XYZ",
        "desc": "XYZ"
    },
    {
        "name": "PQR",
        "desc": "PQR"
    }
 ]
}

My goal is to show the values of name attributes in a dropdown. So, the dropdown should have - ABC, XYZ, PQR.

So in my component, I am calling this service -

processTemplates: Observable<Response>; 
ngOnInit( ) {
  this.workflowDataService.getProcessTemplates()
     .subscribe(function(response) {
       this.processTemplates = response.json();
       console.log(this.processTemplates);
     });
}

In the console.log, I see the below output

JSON output

how can I get the output in a format which can be rendered in a drop down

<select class="form-control dropdown" (ngModel)="processTemplate" 
                name="processTemplate" id="processTemplate" required>
              <option *ngFor="let processTemplate of processTemplates">
                {{ processTemplate.name }}
              </option>
            </select>
kayasa
  • 2,055
  • 8
  • 37
  • 63
  • You can map response to json in your service. `return this.http.get("/assets/jsons/process-templates.json").map(res => res.json());` – arkus Mar 23 '17 at 07:50

2 Answers2

4

Your JSON contains an array inside a object, so you need to extract the array from the object process-templates. Made some other changes as well, rather use fat arrow syntax instead of function, so you don't loose the context this :)

selectedT: any;

getProcessTemplates(): Observable<Response> {
   return this.http.get("/assets/jsons/process-templates.json")
     // extract array from process-templates object
     .map(res => res.json().process-templates) 
}}

Then in your component subscribe:

this.workflowDataService.getProcessTemplates()
  .subscribe(data => {
    this.processTemplates = data;
    console.log(this.processTemplates);
  });

And as for your template, do like John said:

<select [(ngModel)]="selectedTemplate"> 
  <option *ngFor="let processTemplate of processTemplates">{{processTemplate.name}}</option>
</select>
AT82
  • 71,416
  • 24
  • 140
  • 167
  • can you please help me to solve this https://stackoverflow.com/questions/50059278/how-to-bind-api-response-json-to-drop-down-in-angular4 – Nikson Apr 27 '18 at 09:35
0

From a similar question: Binding select element to object in Angular 2

<select [(ngModel)]="selectedTemplate"> // use banana in a box syntax:[()]
  <option *ngFor="let processTemplate of processTemplates" [ngValue]="processTemplate">{{processTemplate.name}}</option>
</select>

Also. You have a different scope for (this) inside your init method. Chaning to a lambda function will solve this. And as mention by @AJT_82, extract the object inside your json

ngOnInit( ) {
  this.workflowDataService.getProcessTemplates()
     .subscribe(response => { //removed function, added =>
       this.processTemplates = response.json().process-templates; //extract json
       console.log(this.processTemplates);
     });
}
Community
  • 1
  • 1
John
  • 10,165
  • 5
  • 55
  • 71
  • The output printed on the console shows that it is not in a format that can be iterated using *ngFor, that's why I still get the same error - Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays. – kayasa Mar 23 '17 at 08:03
  • as @AJT_82 mentions in his/her answer, extract the object inside your json: `this.processTemplates = response.json().process-templates` – John Mar 23 '17 at 08:15