简体   繁体   中英

Angular 2 - API Request not returning Observable, Error: undefined has no property 'length'

EXCEPTION: Uncaught (in promise): Error: Error in http://localhost:3000/app/search/results/templates/search-results.component.html:88:58 caused by: Cannot read property 'length' of undefined TypeError: Cannot read property 'length' of undefined

So, the deal is the POST method seems to be working just fine. The do() logs the proper expected response from the server but somewhere between the getSearchResults() implementation in SearchService and the function call in SearchResultsComponent something is failing. _searchResults never gets updated to any value.

search.service.ts

    getSearchResults(numberOfResults: number, offset: number, sortProperties?: ISort): Observable<ISearchResult[]>{
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });
    let searchParams = localStorage.getItem("savedSearchParameters");

    return this._http.post(this._baseUrl + "customer", searchParams, options)
        .do(r => console.log(r))
        .map((r: Response) => r.json().data as ISearchResult[]);

}

search-results.component.ts

private _searchResults: ISearchResult[];

        this._searchService.getSearchResults(this.numResultsToFetch(), this._resultOffset)
        .subscribe((data: ISearchResult[]) => this._searchResults = data);

search-results.template.html

                <results-table
                    *ngIf="_searchResults.length > 0"
                    (sortEvent)="onSort($event)"
                    [resultsPerPage]="_resultSettings.resultsPerPage"
                    [pageNumber]="_pageNumber"
                    [resultOffset]="_resultOffset"
                    [columnMapping]="_columnMapping"
                    [totalPages]="_totalPages"
                    [columnsToBeDisplayed]="_resultSettings.columnsToBeDisplayed"
                    [displayData]="_searchResults"></results-table>

You need to set private _searchResults: ISearchResult[]; to empty array, because its undefined at the beginning because your request is async, so the component cannot call .length on something that is not yet defined.

Should be: private _searchResults: ISearchResult[] = []

In this case I would use a public getter for the private _searchResults: ISearchSersult[]; . But you don't need to set a value to it. But I'm pretty sure that the template can't access a private variable since it never gets to the $scope . So something like this:

public get searchResults():ISearchResult[]{
    return this._searchResults;
}

and then modify the template:

<results-table
   *ngIf="searchResults.length > 0"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM