Reputation: 533
I have a dropdown in my component. Here is the code of the component:
export class MyComponent {
MyObjectArray: MyObject[] = [];
constructor(private _service: MyService)
}
ngOnInit() {
this._service.get().do((response): MyObject[]) => {
this.MyObjectArray = response;
this.MyObjectArray.forEach((obj) => {
console.log(obj.Code)
});
});
My html is:
<select>
<option [value]="obj.Code" *ngFor="let obj of MyObjectArray; let i = index">{{obj.Code}}</option>
</select>
And in my service:
return this._http.get(_url, this.options)
.map(res => res.json())
.catch(super.handlerError);
I have a console.log
in my code to verify that the service returned something and I am having results. The issue is why is it not binding on my dropdown. I did inspect element and there are no items in my dropdown.
Oh and one thing, I tried putting the ngFor
in a div
with span
inside, it was working. I just don't understand when I put it on my dropdown it doesn't work.
EDIT
Now when I inspect element, I can see my objects. But they are still not appearing in my dropdown. Here is what I changed:
this._service.get().subscribe(response => this.MyObjectArray = response);
EDIT
I also have this code on my ngAfterViewInit()
$('select').material_select();
Upvotes: 0
Views: 876
Reputation: 6535
You have a dropdown which is constructed using asynchronous data. Then you have $('select').material_select()
which instantiates the select and it options.
The problem is that by the time ngAfterViewInit()
lifecycle hook is executed the *ngFor
operation is still in process. You can pass the select element it and inspect it yourself, my guess it that it will not have any options listed.
I had a similar issue and I solved it by creating a directive, add a reference to it on the *ngFor
element, then utilize the built in variable last
- let last = last
, and pass that as input to the directive.
If last === true
then your dropdown is complete and you can instatiate it from the directive using $('select').material_select()
.
You can also use setTimeout
in the hopes of there is no latency in the network that holds things up, in which case the dropdown would not work of course.
Upvotes: 2
Reputation: 58573
Replace your code with this:
this._service.get().subscribe(response => {
this.MyObjectArray = response;
setTimeout(function(){
$('select').material_select();
},200);
});
Code : $('select').material_select();
should init the select box after value init , or you can init on ngAfterViewInit
but then you have to destroy and reinit
on the time you get the data.
You are getting data correctly but the issue is you are initialising the select box before you get the data , so it will not auto update select coz you have already manipulated it with jQuery , you have to reinit , to show updated data.
How to destroy select 2 : http://materializecss.com/forms.html
$('select').material_select('destroy');
Upvotes: 1
Reputation: 40647
Try triggering change detection manually:
import { ChangeDetectorRef } from '@angular/core';
constructor(private cdr: ChangeDetectorRef){...}
this._service.get().subscribe(response => {
console.log(JSON.stringify(response)); // what does this print
this.MyObjectArray = response;
this.cdr.detectChanges();
});
Upvotes: 2