Reputation: 379
I created a directive for my angular project which makes a request to a backend API to fetch a number of countries and then populates the options of a selector with an ngFor. Below you can see how they are structured:
select.component.html:
<div class="col-sm-10" (countriesFetched)="populateCountriesList($event)" appGetCountriesList>
<select id="countrySelector" class="form-control" [(ngModel)]='coutryOption' (ngModelChange)='countrySelected($event)' required>
<option *ngFor="let country of countriesList;" [ngValue]=country [selected]="country.name === countryToDisplay? selected:null">{{country.name}}</option>
</select>
</div>
select.component.ts
@Component({
selector: 'app-selector',
templateUrl: './selector.component.html',
styleUrls: ['./selector.component.scss'],
})
export class SelectorComponent implements OnInit {
@Input('countryToDisplay') countryToDisplay: string
@Output() shippingCountryChanged: EventEmitter<string> = new EventEmitter();
countriesList: Object[];
singleCountry: boolean;
constructor () { }
ngOnInit() {
this.singleCountry = false;
}
populateCountriesList(countries) {
this.countriesList = countries;
}
countrySelected(e) {
this.shippingCountryChanged.emit(e);
}
}
selector.directive.ts
@Directive({
selector: '[appGetCountriesList]'
})
export class DropdownDirective {
@Output() countriesFetched = new EventEmitter<any>();
countrylist: Object[] = [];
constructor ( private countriesService: CountriesService ) {
this.getCountries();
}
getCountries() {
if (this.countrylist.length === 0) {
const market = localStorage.getItem('marketCode');
this.countriesService.fetchCountries(market).subscribe( res => {
res = res['countries'];
Object.keys(res).map( key => {
if ( res[key].name.length > 0 && parseInt(res[key].is_enabled, 10) === 1) {
this.countrylist.push(res[key]);
}
});
this.countrylist = this.countrylist.sort();
this.countriesFetched.emit(this.countrylist);
});
}
}
}
When a country is selected, an event is emitted and the whole application updates itself with the new value.
My question is, how can I have the value that the user has chosen preselected, perhaps after when they refresh the page? I tried to pass in the preselected value as an input to the component, as you can see in the .html file, but the selector is still blank, until the user chooses a new value.
Upvotes: 3
Views: 1560
Reputation: 379
After fiddling around with the select form, it turned out that the [(ngModel)]='coutryOption' was not set to anything in on init.
So i change the component to look like so:
export class CountrySelectorComponent {
@Input('countryToDisplay') countryToDisplay: string;
@Output() shippingCountryChanged: EventEmitter<string> = new EventEmitter();
countriesList: Object[];
countryOption: object;
constructor () { }
populateCountriesList(countries) {
this.countriesList = countries;
this.countryOption = this.countriesList.filter(country => {
return country['name'] === this.countryToDisplay
});
this.countryOption = this.countryOption[0];
}
countrySelected(e) {
this.shippingCountryChanged.emit(e);
}
}
and the html looks like so:
<div class="col-sm-10" (countriesFetched)="populateCountriesList($event)" appGetCountriesList>
<select id="countrySelector" class="form-control" [(ngModel)]='countryOption' (ngModelChange)='countrySelected($event)' required>
<option *ngFor="let country of countriesList;" [ngValue]=country >{{country.name}}</option>
</select>
</div>
This works for its' intended purpose. Thank you for you answers!
Upvotes: 1
Reputation: 158
Similar to the @Praveen Kumar answer but what I use if it helps any:
<select class="form-control" [(ngModel)]="countryOption">
<ng-template [ngIf]="select">
<option value=''>{{select}}</option>
<option *ngFor="let country of countryList" type="text" [ngValue]="country.name">{{country.name}}</option>
</ng-template>
<ng-template [ngIf]="!select">
<option *ngFor="let country of countryList" type="text" [ngValue]="country.name">{{country.name}}</option>
</ng-template>
</select>
Upvotes: 1
Reputation: 543
This might be a very crude way of doing it:
<select id="countrySelector" class="form-control" [(ngModel)]='coutryOption' (ngModelChange)='countrySelected($event)' required>
<ng-container *ngFor="let country of countriesList;">
<ng-container *ngIf="country.name === countryToDisplay">
<option [ngValue]=country selected>{{country.name}}
</option>
</ng-container>
<ng-container *ngIf="country.name !== countryToDisplay">
<option [ngValue]=country>{{country.name}}
</option>
</ng-container>
</ng-container>
</select>
Upvotes: 1