Reputation: 359
I have a service :
@Injectable()
export class LostFoundEditService {
public lostForm: FormGroup;
public countries: any[] = [];
private countriesUrl = 'assets/countries.json';
constructor(private http: HttpClient) { }
init() {
this.initForm();
this.http.get(this.countriesUrl).subscribe(data => {
this.countries = this.countries.concat(data['countries']);
},
(err: HttpErrorResponse) => {
console.log(err.message);
});
}
private initForm() {
this.lostForm = new FormGroup({
'title': new FormControl('', Validators.required),
'description': new FormControl('', Validators.required),
'country': new FormControl('', Validators.required),
'state': new FormControl('', Validators.required),
'city': new FormControl('', Validators.required),
'zipCode': new FormControl(''),
'street': new FormControl('')
});
}
}
and a class thats uses this service :
@Component({
selector: 'app-lost-edit',
templateUrl: './lost-edit.component.html',
styleUrls: ['./lost-edit.component.css']
})
export class LostEditComponent implements OnInit {
lostForm: FormGroup;
countries: any[] = [];
states: any[] = [];
cities: any[] = [];
constructor(
private http: HttpClient,
private lostFoundEditService: LostFoundEditService) { }
ngOnInit() {
this.lostFoundEditService.init();
this.lostForm = this.lostFoundEditService.lostForm;
this.countries = this.lostFoundEditService.countries;
}
onCancel() {
}
}
Also I have the template associated with that class :
(...)
<select
id="country"
formControlName="country"
class="form-control">
<option value="">Countries</option>
<option *ngFor="let country of countries" value="{{country['id']}}">{{country['name']}}</option>
</select>
</div>
</div>
</div>
(...)
My question is : how to wait for the end of subscribe method (in init()
of LostFoundEditService
) to have all countries of the json file entered in countries
array of LostEditComponent
. Nothing appears in the dropdown list for the moment...
Upvotes: 1
Views: 6942
Reputation: 132
You could possibly try this.
What i'm doing here is changing the countries property from an Array to a BehaviourSubject which means your component can subscribe to this property. We can subscribe by using the async pipe in your template which in the angular world calls the subscribe.
In your service, when we finish getting the data via the subscribe you can set the value by doing this.countries.next(data['countries']).
service :
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
@Injectable()
export class LostFoundEditService {
public lostForm: FormGroup;
public countries: Subject = new BehaviorSubject<Array<any>>(null);
private countriesUrl = 'assets/countries.json';
constructor(private http: HttpClient) { }
init() {
this.initForm();
this.http.get(this.countriesUrl).subscribe(data => {
this.countries.next(this.countries.concat(data['countries']));
},
(err: HttpErrorResponse) => {
console.log(err.message);
});
}
private initForm() {
this.lostForm = new FormGroup({
'title': new FormControl('', Validators.required),
'description': new FormControl('', Validators.required),
'country': new FormControl('', Validators.required),
'state': new FormControl('', Validators.required),
'city': new FormControl('', Validators.required),
'zipCode': new FormControl(''),
'street': new FormControl('')
});
}
}
component :
@Component({
selector: 'app-lost-edit',
templateUrl: './lost-edit.component.html',
styleUrls: ['./lost-edit.component.css']
})
export class LostEditComponent implements OnInit {
lostForm: FormGroup;
countries;
states: any[] = [];
cities: any[] = [];
constructor(
private http: HttpClient,
private lostFoundEditService: LostFoundEditService) { }
ngOnInit() {
this.lostFoundEditService.init();
this.lostForm = this.lostFoundEditService.lostForm;
this.countries = this.lostFoundEditService.countries;
}
onCancel() {
}
}
template :
(...)
<select
id="country"
formControlName="country"
class="form-control">
<option value="">Countries</option>
<option *ngFor="let country of countries | async" value="{{country['id']}}">{{country['name']}}</option>
</select>
</div>
</div>
</div>
(...)
Upvotes: 1