Here is my scenario I have component for the end user to enter the state and associate the country for that state. For some reason the country dropdown is not getting populated with countries for the foreign key. Can someone please help?
Here is how my html is structured -
<div class="control-section">
<ejs-grid #countryStateGrid id="countryStateGrid" [dataSource]="data | async" [allowPaging]="true" [pageSettings]="pageSettings" [editSettings]="editSettings" [toolbar]="toolbar"
(dataSourceChanged)="dataSourceChanged($event)" (dataStateChange)="dataStateChange($event)" allowSorting="true" (actionComplete)="actionComplete($event)"
[allowMultiSorting]="false">
<e-columns>
<e-column field="id" headerText="Id" width="120" textAlign="Right" isPrimaryKey="true" [visible]="false"></e-column>
<e-column field="stateName" headerText="State" width="200"></e-column>
<e-column field="stateAbbr" headerText="State Abbreviation" width="200"></e-column>
<e-column field="countryId" headerText="Country" width="200" [visible]="false" foreignKeyValue='countryName' foreignKeyField='id' [dataSource]='countryData'></e-column>
<e-column field="createdBy" headerText="CreatedBy" width="50" [visible]="false"></e-column>
<e-column field="createdDate" headerText="CreatedDate" width="50" [visible]="false"></e-column>
<e-column field="modifiedBy" headerText="ModifiedBy" width="50" [visible]="false"></e-column>
<e-column field="modifiedDate" headerText="ModifiedDate" width="50" [visible]="false"></e-column>
</e-columns>
Here is how I am associated my state data to the grid
export class CountryStateComponent implements OnInit {
public pageSettings: Object;
public editSettings: Object;
public data: Observable<DataStateChangeEventArgs>;
public countryData: ICountry[];
public toolbar: string[];
constructor(private authService: MsalService, private service: CountryStateService, private countryService: CountryService, private broadcastService: BroadcastService) {
this.data = service;
}
ngOnInit() {
if (!(!!this.authService.getAccount())) {
this.login();
}
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: false, mode: 'Dialog' };
this.toolbar = ['Add', 'Edit', 'Update', 'Cancel'];
this.pageSettings = { pageCount: 4, pageSize: 20 };
this.getCountries();
//console.log(this.countryData);
this.getCountryStates();
}
getCountries() {
this.countryService.getCountries().subscribe({
next: (response: ICountry[]) => {
this.countryData = response;
console.log(this.countryData);
this.getCountryStates();
}
});
}
getCountryStates(): void {
const state: any = { skip: 0, take: 20 };
console.log("Reached here");
this.service.executeCountryStates(state);
}
public dataStateChange(state: any): void {
//this.getData();
this.service.executeCountryStates(state);
}
public dataSourceChanged(state: any): void {
if (state.action === 'add') {
this.service.addCountryState(state).subscribe(() => { }, error => console.log(error), () => {
state.endEdit();
});
} else if (state.action === 'edit') {
this.service.updateCountryState(state).subscribe(() => {
state.endEdit();
}, (e) => {
this.countryStateGridObj.closeEdit();
}
);
}
else if (state.requestType === 'delete') {
//this.groupEventCategoryService.deleteGroupEventCategory(state).subscribe(() => {
// state.endEdit();
//});
}
}
actionComplete(args: DialogEditEventArgs): void {
//console.log(args);
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
if (args.requestType === "add") {
args.dialog.header = "Add state / province for country";
}
else {
args.dialog.header = `Edit state / province - ${(<ICountryState>args.rowData).stateName}`;
}
if (Browser.isDevice) {
args.dialog.height = window.innerHeight - 90 + 'px';
(<Dialog>args.dialog).dataBind();
}
}
}
}
The country and countrystate service is setup similar to this -
import { Injectable } from '@angular/core';
import { Observable, of, from, Subject} from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ICountry } from './../models/country.model';
import * as config from '../app-config.json';
import { BroadcastService, MsalService } from '@azure/msal-angular';
import { InteractionRequiredAuthError, AuthError } from 'msal';
import { DataStateChangeEventArgs, DataSourceChangedEventArgs } from '@syncfusion/ej2-grids';
@Injectable()
export class CountryService extends Subject<DataStateChangeEventArgs> {
apiUrl = config.resources.countryAPI.resourceUri;
constructor(private http: HttpClient, private authService: MsalService) { super(); }
public executeCountry(state: any): void {
//let loggedin: boolean = !!this.authService.getAccount();
this.getCountry(state).subscribe(x => super.next(x as DataStateChangeEventArgs));
}
getCountries(): Observable<ICountry[]> {
return this.http.get<ICountry[]>(this.apiUrl)
.pipe(catchError(this.handleError<ICountry[]>('getCountries')));
}
getCountry(state: any): Observable<ICountry[]> {
return this.http.get<ICountry[]>(this.apiUrl)
.pipe(map((response: any) => ({
result: state.take > 0 ? (state.skip > 0 ? response.slice(state.skip, state.take + state.skip) : response.slice(0, state.take)) : response,
count: response.length
} as any)), map((data: any) => data), catchError(this.handleError<ICountry[]>('getCountry')));
//return this.http.get<ICountry[]>(this.apiUrl)
// .pipe(catchError(this.handleError<ICountry[]>('getCountry', [])));
}
addCountry(state: any): Observable<ICountry> {
return this.http.post<ICountry>(this.apiUrl, state.data)
.pipe(catchError(this.handleError<ICountry>('addCountry', null)));
}
updateCountry(state: any): Observable<ICountry> {
return this.http.put<ICountry>(this.apiUrl, state.data)
.pipe(catchError(this.handleError<ICountry>('updateCountry', null)));
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
return of(result as T);
}
}
}