0

I have a element in component.html:

<select name="select1">
    <option *ngFor="let option of optionsArr">{{option}}</option>
</select>

Inside component.ts, I am populating optionsArr from Excel:

export class ComponentX implements OnInit {
optionsArr = [];

constructor(private service : ServiceX) { 
}

ngOnInit() { 
   this.service.getJSON(filepath).subscribe((jsonObj:any)=> {
        for (var x in jsonObject){
            this.optionsArr.push(x);
        }
   });
}

In service.ts

export class ServiceX {
   constructor() {}
   getJSON(filepath){
      return Observable.create((observer:any) =>{
          //retrieve JSON here
          observer.next(jsonObj);
          observer.complete();
      });
   }
}

But clicking the drop down, nothing appears. I am guessing the view has been loaded before optionsArr has been populated. So my question is, is there a way around this?

3
  • 2
    if your service return observable(which it would be) subscribe to it and populate the option list in subscription or try using async pipe. Commented Jul 9, 2018 at 8:08
  • show the code with service call ? Commented Jul 9, 2018 at 8:09
  • see the console and get stack trace of error & also show us. Commented Jul 9, 2018 at 8:10

3 Answers 3

2

Assuming your service call is a normal synchronous call, you don't need to worry about the view or the array being initialized first. Angular redraws the view if variables change. If your call is asynchronous, bind it to an observable and use the async pipe in your view (See docs).

Example:

<select name="select1" *ngIf="optionsArr | async as options">
    <option *ngFor="let option of options">{{option}}</option>
</select>

You don't need to subscribe to the observable, instead, bind it as your options array:

optionsArr: Observable<string[]> // Assuming the array is of type string

ngOnInit(){
  this.optionsArr = this.service.getJSON(filepath) as Observable<string[]>;
}
Sign up to request clarification or add additional context in comments.

2 Comments

I had bind it to observable. Please check my edits above. How do I use sync pipe in my view. Can you direct me to example? I am new to angular.
Updated my answer ;)
0

Normally you would do

ngOnInit(){
   this.service.yourServiceCallThatReturnsObservable().subscribe(options=>{
       for (var x in options){
        this.optionsArr.push(x);
       } 
   }
}

but thats assuming you are making service call that returns Observable<Someting>

In case of sync call, it should just work as you have presented.

3 Comments

Actually, that's how my service is, check my edits above.
So it will work as I described. Subscribe to observable as long as you create proper observable.
Oddly it doesnt work. Any idea what else may be the problem?
0

Inside component.ts

public optionsArr: any;


ngOnInit() { 
   this.service.getJSON(filepath).subscribe(
    (jsonObj:any)=> {
        this.optionsArry = jsonObj.options;
        //SEE THE RESULT IN CONSOLE
        console.log(this.optionsArry)
   });
}

In service.ts

export class ServiceX {
   constructor() {}
   public getJSON(filepath): Observable<any> {
         return this.http.get(filepath)
                         .map((res:any) => //retrieve JSON here)
                         .catch((error:any) => console.log(error));
     });
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.