Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
335 views
in Technique[技术] by (71.8m points)

asp.net web api - Angular 5: 'Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays'

I have tried looking for answers in here, but havent found any that can be applied to me so here goes.I am trying to get a list of employments from .net backend and everyting is working fine until i try to *NgFor in the view.
I have tried adding for example 'employees.EmploymentList' to the response, but then I get 'Property 'Employmentlist' does not exist on type 'IListItem[]'

This i my app:

my list component, and ill post the console log in the bottom of the post.

export class EmployeeListComponent {

unitIdParam: string;
orgNoParam: string;
employeeList: EmployeeListItemComponent[];
errorMessage: string;


_ListFilter: string;
get listFilter(): string {
    return this._ListFilter;
}
set listFilter(value: string) {
    this._ListFilter = value;
    this.filteredEmployees = this.listFilter ? this.performFilter(this.listFilter) : this.employees;
}

@Input()
names: any[];

filteredEmployees: IListItem[] = [];
employees: IListItem[] = [];

constructor(elm: ElementRef, private apiService: ApiService, private route: ActivatedRoute) {
    this.names = elm.nativeElement.getAttribute('names');

    this.route.params.subscribe(params => {
        this.orgNoParam = params['orgNoParam'];
        this.unitIdParam = params['unitIdParam'];
    });
}

ngOnInit(): void {
    this.apiService.getEmploymentList(this.orgNoParam, this.unitIdParam)
        .subscribe(employees => {
            this.employeeList = employees;
            this.filteredEmployees = this.employeeList;
            console.log(this.filteredEmployees);
        },
        error => this.errorMessage = <any>error);
}

performFilter(filterBy: string): IListItem[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.employees.filter((employee: IListItem) =>
        employee.Name.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

}

my api service

@Injectable()
export class ApiService {
//Set url
private employmentListUrl = 'api/employment/list';

constructor(private http: HttpClient) { }

getEmploymentList(orgNoParam: string, unitIdParam: string): Observable<IListItem[]> {
    //set headers
    let head = new HttpHeaders();
    head = head.append('Content-Type', 'application/json');

    //set params
    let params = new HttpParams();
    params = params.append('orgNoParam', orgNoParam);
    params = params.append('unitIdParam', unitIdParam);

    let data = {
        "orgNoParam": orgNoParam,
        "unitIdParam": unitIdParam
    };
    let body = JSON.stringify(data)

    //api call
    return this.http.post<IListItem[]>(this.employmentListUrl, body, { headers: head })
        .do(data => JSON.stringify(data))
        .catch(this.handleError);
}

private handleError(err: HttpErrorResponse) {
    console.log(err.message);
    return Observable.throw(err.message);
}

}

enter image description here

   </thead>
    <tbody>
        <tr class="gridrow" *ngFor="let employee of filteredEmployees">
            <td><input type="checkbox"></td>
            <td>
                {{employee.PersonKey._displayValue}}
            </td>
            <td>
                <a rel="popover" href="/{{ employee.EmploymentReference.OrganizationRegistrationNumber.FullValue }}/employment/{{ employee.EmploymentReference.NationalCivicRegistrationNumber.FullValue }}/info" class="name-employment new-style " data-parent-org-name="">{{employee.Name}}</a>
            </td>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The very problem is that the types you have made for yourself are invalid because the request from api returns something like {EmploymentList: IListItem[]}

Should be working if you modify the code within the service as

getEmploymentList(orgNoParam: string, unitIdParam: string): Observable<IListItem[]> {
...
//api call
return this.http.post<{EmploymentList: IListItem[]}>(this.employmentListUrl, body, { headers: head })
    .map(data => data.EmploymentList)
    .catch(this.handleError);
}

The "problem" with typescript is, that types are just your wish, not something enforced by runtime. This is especialy obvious in code interfacing with backend or so - you may just expect some format of data being returned

EDIt: Some spelling


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...