在遍历两个数组时无法读取未定义的属性'id':Angular

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在遍历两个数组时无法读取未定义的属性'id':Angular相关的知识,希望对你有一定的参考价值。

我认为我可能缺少一些小东西,或者我没有正确实现我的角度代码。不过,我当前收到的错误是:

TypeError:无法读取未定义的属性'id'

我正在尝试在我的[[newsfeed.component.html(模板)中调用一个函数,该函数调用一个具有id并循环遍历两个数组的函数,这些数组定义在我的[[< [newsfeed.component.ts(组件)(请参见下文)

newsfeed.component.ts:import { Component, OnInit, Input, OnChanges, SimpleChanges } from "@angular/core"; //import { FeedService } from "src/app/core/news-feed"; import { FeedService } from "../../../core/news-feed/_services/feed.service.fake"; import { CustomersService } from "../../../core/e-commerce"; import { MockFeedTable } from "../../../core/news-feed/_server/feed.mock-table"; import moment from "moment"; import { Observable } from "rxjs"; import { SearchPipe } from "../../partials/_pipes/search.pipe"; import { FeedTagsService } from "../../../../../src/app/core/news-feed/_services/feed-tags.service"; import { ActivatedRoute } from "@angular/router"; export interface MOCK_UserData { id: number; userName: string; profileImagePath: string; } export interface MOCK_NewsPost { id: number; bookmarkCount: number; commentCount: number; timeLastUpdated: string; } @Component({ selector: "kt-news-feed", templateUrl: "./news-feed.component.html", styleUrls: ["./news-feed.component.scss"] }) export class NewsFeedComponent implements OnInit { filterQuery: any; componentDataLoaded: boolean; constructor( private feedService: FeedService, private feedTagsService: FeedTagsService, private route: ActivatedRoute ) {} MOCK_UserDataTable: MOCK_UserData[] = [ { id: 1, userName: "NUS", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/nus-logo.jpg" }, { id: 2, userName: "POWERLEAGUE Student", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/powerleague-logo.png" }, { id: 3, userName: "NUS", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/nus-logo.jpg" }, { id: 4, userName: "Northumbria University", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/northumbria-uni-logo.png" }, { id: 5, userName: "Northumbria Mens Football", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/team-northumbria-logo.jpg" }, { id: 6, userName: "Northumbria Students Union", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/nsu-logo.jpg" }, { id: 7, userName: "Student Finance England", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/sfe-logo.png" }, { id: 8, userName: "Amazon Prime Student", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/amazon-prime-logo.jpg" }, { id: 9, userName: "Google Scholarships", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/google-logo.png" }, { id: 10, userName: "Northumbria University", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/northumbria-uni-logo.png" }, { id: 11, userName: "Northumbria BSc Accounting And Finance", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/af-logo.png" }, { id: 12, userName: "Northumbria Students Union", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/nsu-logo.jpg" }, { id: 13, userName: "Lost Property", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/lp-logo.png" }, { id: 14, userName: "Northumbria University Campus 24 Hour Security", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/24h-logo.png" }, { id: 15, userName: "Northumbria University Examiners Office", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/eo-logo.png" }, { id: 16, userName: "Enterprise Society", profileImagePath: "../../../../assets/media/stuserve-mock-post-users/es-logo.png" } ]; NEWS_DATA: any; NEWS_TAG_DATA: any; currentNewsQuery: any; ngOnInit() { this.componentDataLoaded = false; this.route.data.subscribe(res => { this.NEWS_DATA = res.newsfeed; console.log(res.newsfeed); this.NEWS_TAG_DATA = res.newsfeedtags; console.log(res.newsfeedtags); }); } waitForComponentData() { console.log("Entered waitForComponentData"); console.log(" componentDataLoaded is currently : "); console.log(this.componentDataLoaded); this.componentDataLoaded = true; console.log(" componentDataLoaded is now : "); console.log(this.componentDataLoaded); } filterNewsPosts() { return this.feedService.retrieveSearchBarQuery(); } getUserProfilePictureFromUserId(userId) { for (var i = 0, len = this.MOCK_UserDataTable.length; i < len; i++) { if (this.MOCK_UserDataTable[i].id == userId) { return this.MOCK_UserDataTable[i].profileImagePath; } } } getUserNameFromUserId(userId) { for (var i = 0, len = this.MOCK_UserDataTable.length; i < len; i++) { if (this.MOCK_UserDataTable[i].id == userId) { return this.MOCK_UserDataTable[i].userName; } } } getNewsPostElapsedTime(startDate) { return moment(startDate).fromNow(); } getFilterTagIdsFromNewsPost(postId: any) { console.log( "getFilterTagIdsFromNewsPost : postId from parameter is: " + postId ); for (var i = 0; i <= this.NEWS_DATA.length; i++) { if (postId == this.NEWS_DATA[i].id) { console.log( "getFilterTagIdsFromNewsPost : returning the following tags: " + this.NEWS_DATA[i].postTags ); return this.NEWS_DATA[i].postTags; } } } getFilterTagsFromNewsPost(postId: any) { var tagIdArray = this.getFilterTagIdsFromNewsPost(postId); let newsDataArray = this.NEWS_DATA; let newsTagDataArray = this.NEWS_TAG_DATA; var resultTagArray = []; console.log("tagIdArray for Post with id of " + postId + " is :"); console.log(tagIdArray); console.log("Looping through first loop..."); for (var i = 0; i <= tagIdArray.length; i++) { console.log("Looping through second loop..."); for (var j = 0; j <= newsTagDataArray.length; j++) { if (tagIdArray[i] == newsTagDataArray[j].id) { resultTagArray.push(newsTagDataArray[j]); } } } console.log("Final Array for this post is: "); console.log(resultTagArray); return resultTagArray; } }

newsfeed.component.html:

<!-- Left col -->
<!-- <div class="row" *ngIf="!componentDataLoaded">
    <div class="col-sm">
        <div
            class="kt-spinner kt-spinner--v2 kt-spinner--lg kt-spinner--info"
        ></div>
    </div>
</div> -->
<div class="row">
    <div class="col-lg-6">
        <ng-container
            *ngFor="
                let newsData of NEWS_DATA | NewsStringFilter: filterNewsPosts()
            "
        >
            <!-- CARD START -->
            <div *ngIf="!newsData.oddNewsPostInDatabase" class="kt-portlet">
                <div class="kt-portlet__head" style="margin-top: 15px;">
                    <div class="kt-portlet__head-label">
                        <span class="kt-portlet__head-icon">
                            <a
                                href="#"
                                class="kt-media kt-media--lg kt-media--circle"
                            >
                                <img
                                    src="{{
                                        getUserProfilePictureFromUserId(
                                            newsData._userId
                                        )
                                    }}"
                                    alt="profile-image"
                                />
                            </a>
                        </span>
                        <h3 class="kt-portlet__head-title">
                            {{ getUserNameFromUserId(newsData._userId) }}
                        </h3>
                    </div>
                    <div class="kt-portlet__head-toolbar">
                        {{ getNewsPostElapsedTime(newsData._createdDate) }}
                    </div>
                </div>
                <div class="kt-portlet__body">
                    <h4>
                        {{ newsData.postHeader }}
                    </h4>
                    {{ newsData.postBody }}
                </div>
                <div class="kt-portlet__foot">
                    <div class="kt-portlet__head-toolbar">
                        <div class="kt-portlet__head-actions">
                            <ng-container
                                *ngFor="
                                    let newsTag of getFilterTagsFromNewsPost(
                                        newsData.id
                                    )
                                "
                            >
                                <td class="card-tag-container">
                                    <span
                                        class="kt-badge kt-badge--inline cat-tab"
                                        [style.background-color]="
                                            newsTag.tagColour
                                        "
                                        style="color: #ffffff"
                                        >{{ newsTag.tagTitle }}</span
                                    >
                                </td>
                            </ng-container>
                            <a
                                href="#"
                                class="btn btn-outline-brand btn-sm btn-icon btn-icon-md"
                            >
                                <i
                                    class="flaticon2-tag
                            "
                                ></i>
                            </a>
                            <a
                                href="#"
                                class="btn btn-outline-brand btn-sm btn-icon btn-icon-md"
                            >
                                <i class="flaticon-comment"></i>
                            </a>
                        </div>
                    </div>
                </div>
            </div>
            <!-- CARD END -->

            <!-- CARD END -->
        </ng-container>
    </div>

    <!-- Right col -->

    <div class="col-lg-6">
        <ng-container
            *ngFor="
                let newsData of NEWS_DATA | NewsStringFilter: filterNewsPosts()
            "
        >
            <!-- CARD START -->
            <div *ngIf="newsData.oddNewsPostInDatabase" class="kt-portlet">
                <div class="kt-portlet__head" style="margin-top: 15px;">
                    <div class="kt-portlet__head-label">
                        <span class="kt-portlet__head-icon">
                            <a
                                href="#"
                                class="kt-media kt-media--lg kt-media--circle"
                            >
                                <img
                                    src="{{
                                        getUserProfilePictureFromUserId(
                                            newsData._userId
                                        )
                                    }}"
                                    alt="profile-image"
                                />
                            </a>
                        </span>
                        <h3 class="kt-portlet__head-title">
                            {{ getUserNameFromUserId(newsData._userId) }}
                        </h3>
                    </div>
                    <div class="kt-portlet__head-toolbar">
                        {{ getNewsPostElapsedTime(newsData._createdDate) }}
                    </div>
                </div>
                <div class="kt-portlet__body">
                    <h4>
                        {{ newsData.postHeader }}
                    </h4>
                    {{ newsData.postBody }}
                </div>
                <div class="kt-portlet__foot">
                    <div class="kt-portlet__head-toolbar card-footer-toolbar">
                        <div class="kt-portlet__head-actions">
                            <ng-container
                                *ngFor="
                                    let newsTag of getFilterTagsFromNewsPost(
                                        newsData.id
                                    )
                                "
                            >
                                <td class="card-tag-container">
                                    <span
                                        class="kt-badge kt-badge--inline cat-tab"
                                        [style.background-color]="
                                            newsTag.tagColour
                                        "
                                        style="color: #ffffff"
                                        >{{ newsTag.tagTitle }}</span
                                    >
                                </td>
                            </ng-container>
                            <a
                                href="#"
                                class="btn btn-outline-brand btn-sm btn-icon btn-icon-md"
                            >
                                <i
                                    class="flaticon2-tag
                                    "
                                ></i>
                            </a>
                            <a
                                href="#"
                                class="btn btn-outline-brand btn-sm btn-icon btn-icon-md"
                            >
                                <i class="flaticon-comment"></i>
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </ng-container>
        <!-- CARD END -->
    </div>
</div>

最初,我认为该视图执行了相关功能:(getFilterTagsFromNewsPost(newsData.id))在通过可观察的填充变量(

NEWS_DATA和

NEWS_TAG_DATA)将数据加载到组件中并因此抛出“ undefined”之前。

因此,我尝试将分解器实现,希望这是问题所在,事实证明我仍然做错了。解析程序和服务的代码如下:feed.service.fake.ts

// Angular import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; // RxJS import { Observable, forkJoin, of } from "rxjs"; import { mergeMap, delay } from "rxjs/operators"; // Lodash import { each } from "lodash"; // CRUD import { HttpUtilsService, QueryParamsModel, QueryResultsModel } from "../../_base/crud"; // Models import { NewsPostModel } from "../_models/news-post.model"; const API_NEWS_POST_URL = "api/newsfeed"; // Fake REST API (Mock) // This code emulates server calls @Injectable() export class FeedService { NEWS_FEED_ITEMS_STORAGE: any; public currentSearchBarQuery: any; constructor( private http: HttpClient, private httpUtils: HttpUtilsService ) {} // CREATE => POST: add a new newsPost to the server createNewsPost(newsPost: NewsPostModel): Observable<NewsPostModel> { // Note: Add headers if needed (tokens/bearer) const httpHeaders = this.httpUtils.getHTTPHeaders(); return this.http.post<NewsPostModel>(API_NEWS_POST_URL, newsPost, { headers: httpHeaders }); } // READ getAllNewsPosts(): Observable<NewsPostModel[]> { return this.http.get<NewsPostModel[]>(API_NEWS_POST_URL); } getNewsPostById(newsPostId: number): Observable<NewsPostModel> { return this.http.get<NewsPostModel>( API_NEWS_POST_URL + `/${newsPostId}` ); } // Method from server should return QueryResultsModel(items: any[], totalsCount: number) // items => filtered/sorted result findNewsPosts( queryParams: QueryParamsModel ): Observable<QueryResultsModel> { // This code imitates server calls const url = API_NEWS_POST_URL; return this.http.get<NewsPostModel[]>(API_NEWS_POST_URL).pipe( mergeMap(res => { const result = this.httpUtils.baseFilter(res, queryParams, [ "status", "type" ]); return of(result); }) ); } // UPDATE => PUT: update the newsPost on the server updateNewsPost(newsPost: NewsPostModel): Observable<any> { const httpHeader = this.httpUtils.getHTTPHeaders(); return this.http.put(API_NEWS_POST_URL, newsPost, { headers: httpHeader }); } // UPDATE Status updateStatusForNewsPost( newsPosts: NewsPostModel[], status: number ): Observable<any> { const tasks$ = []; each(newsPosts, element => { const _newsPost = Object.assign({}, element); _newsPost.status = status; tasks$.push(this.updateNewsPost(_newsPost)); }); return forkJoin(tasks$); } // DELETE => delete the newsPost from the server deleteNewsPost(newsPostId: number): Observable<any> { const url = `${API_NEWS_POST_URL}/${newsPostId}`; return this.http.delete<NewsPostModel>(url); } deleteNewsPosts(ids: number[] = []): Observable<any> { const tasks$ = []; const length = ids.length; // tslint:disable-next-line:prefer-const for (let i = 0; i < length; i++) { tasks$.push(this.deleteNewsPost(ids[i])); } return forkJoin(tasks$); } fetchSearchBarQuery(value: any): any { this.currentSearchBarQuery = value; } retrieveSearchBarQuery(): any { return this.currentSearchBarQuery; } }

feed-tags.service.ts

// Angular
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
// RxJS
import { Observable } from "rxjs";
// CRUD
import {
    HttpUtilsService,
    QueryParamsModel,
    QueryResultsModel
} from "../../_base/crud";
// Models
import { NewsPostTagModel } from "../_models/news-post-tag.model";

const API_NEWS_POST_TAG_URL = "api/newsfeedtags";

@Injectable()
export class FeedTagsService {
    NEWS_TAG_STORAGE: any;
    SELECTED_NEWS_TAG_STORAGE: any;

    constructor(
        private http: HttpClient,
        private httpUtils: HttpUtilsService
    ) {}

    // CREATE =>  POST: add a new NewsPost to the server
    createNewsPostTag(
        newsPostTag: NewsPostTagModel
    ): Observable<NewsPostTagModel> {
        // Note: Add headers if needed (tokens/bearer)
        const httpHeaders = this.httpUtils.getHTTPHeaders();
        return this.http.post<NewsPostTagModel>(
            API_NEWS_POST_TAG_URL,
            newsPostTag,
            {
                headers: httpHeaders
            }
        );
    }

    // READ
    getAllNewsPostsTags(): Observable<NewsPostTagModel[]> {
        return this.http.get<NewsPostTagModel[]>(API_NEWS_POST_TAG_URL);
    }

    getNewsPostTagsById(newsPostTagId: number): Observable<NewsPostTagModel> {
        return this.http.get<NewsPostTagModel>(
            API_NEWS_POST_TAG_URL + `/${newsPostTagId}`
        );
    }

    // Method from server should return QueryResultsModel(items: any[], totalsCount: number)
    // items => filtered/sorted result
    // Server should return filtered/sorted result
    findNewsPostsTags(
        queryParams: QueryParamsModel
    ): Observable<QueryResultsModel> {
        // Note: Add headers if needed (tokens/bearer)
        const httpHeaders = this.httpUtils.getHTTPHeaders();
        const httpParams = this.httpUtils.getFindHTTPParams(queryParams);

        const url = API_NEWS_POST_TAG_URL + "/find";
        return this.http.get<QueryResultsModel>(url, {
            headers: httpHeaders,
            params: httpParams
        });
    }

    // UPDATE => PUT: update the NewsPost on the server
    updateNewsPostTag(newsPostTag: NewsPostTagModel): Observable<any> {
        const httpHeader = this.httpUtils.getHTTPHeaders();
        return this.http.put(API_NEWS_POST_TAG_URL, newsPostTag, {
            headers: httpHeader
        });
    }

    // UPDATE Status
    updateStatusForNewsPostTagModel(
        newsPostsTags: NewsPostTagModel[],
        status: number
    ): Observable<any> {
        const httpHeaders = this.httpUtils.getHTTPHeaders();
        const body = {
            newsPostsForUpdate: newsPostsTags,
            newStatus: status
        };
        const url = API_NEWS_POST_TAG_URL + "/updateStatus";
        return this.http.put(url, body, { headers: httpHeaders });
    }

    // DELETE => delete the newsPost from the server
    deleteNewsPostTag(newsPostTagId: number): Observable<NewsPostTagModel> {
        const url = `${API_NEWS_POST_TAG_URL}/${newsPostTagId}`;
        return this.http.delete<NewsPostTagModel>(url);
    }

    deleteNewsPostsTags(ids: number[] = []): Observable<any> {
        const url = API_NEWS_POST_TAG_URL + "/deleteNewsPostsTags";
        const httpHeaders = this.httpUtils.getHTTPHeaders();
        const body = { newsPostIdsForDelete: ids };
        return this.http.put<QueryResultsModel>(url, body, {
            headers: httpHeaders
        });
    }
}

news-feed-tags.resolve.tsNews Feed Tags resolve Image

news-feed.resolve.ts:News feed resolve image

这里是带有各种日志和错误的控制台:Logs and Errors Image

如您所见,数据似乎正在通过日志中输出的各个值(特别是id值)传递,但是似乎在数组中的隐藏元素上引发了错误?目前不知道。
答案
i <= tagIdArray.lengthi < tagIdArray.lengthj <= newsTagDataArray.lengthj < newsTagDataArray.length
注意以下内容如何打印未定义,因为x[x.length]始终是未定义的。 

x = [10, 11, 12]; for (var i = 0; i <= x.length; i++) { console.log(x[i]); }

以上是关于在遍历两个数组时无法读取未定义的属性'id':Angular的主要内容,如果未能解决你的问题,请参考以下文章

遍历对象数组-TypeError:无法读取未定义的属性“名称”

Discord.js TypeError:无法读取未定义的属性'id'-channel.id

无法读取未定义的属性'$ valid'

无法读取 nativescript angular2 中未定义的属性全局数组

在props中得到的问题是 "无法读取未定义的属性'map'" [重复] 。

对象数组:无法读取 onchange 事件中未定义的属性“id”