最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular typeScript nested Array is not iterable? - Stack Overflow

programmeradmin0浏览0评论

I have a model class "EventDeatails" like this

export class EventDetails {
  id: string;
  title: string;
  club: string;
  des: string;
  img: string;
  date: string;
  status: number;
}

then I assign values to this from firebase like this

showingEventList: EventDetails[];

this.eventDetails.getOldEvents().subscribe(actionArray => {
  this.showingEventList = actionArray.map(item => {
    return {
      id: item.payload.doc.id,
      ...item.payload.doc.data()
    } as EventDetails ;
  });
});

now I need to add only the club property of this object to another array called clubs[] I did it like this

for ( const item  of this.showingEventList ) {
      this.clubs.push(item.club);
    }

but console shows there is an error:- " showingEventList is not iterable " how can I fix this ????

I have a model class "EventDeatails" like this

export class EventDetails {
  id: string;
  title: string;
  club: string;
  des: string;
  img: string;
  date: string;
  status: number;
}

then I assign values to this from firebase like this

showingEventList: EventDetails[];

this.eventDetails.getOldEvents().subscribe(actionArray => {
  this.showingEventList = actionArray.map(item => {
    return {
      id: item.payload.doc.id,
      ...item.payload.doc.data()
    } as EventDetails ;
  });
});

now I need to add only the club property of this object to another array called clubs[] I did it like this

for ( const item  of this.showingEventList ) {
      this.clubs.push(item.club);
    }

but console shows there is an error:- " showingEventList is not iterable " how can I fix this ????

Share Improve this question edited Oct 6, 2019 at 7:06 Yaser Darzi 1,47813 silver badges26 bronze badges asked Oct 6, 2019 at 7:04 Priyashan JayasankhaPriyashan Jayasankha 3121 gold badge2 silver badges10 bronze badges 4
  • Remember that Observables are async so place for loop in subscribe function. Or You will have for loop of unassigned array. – Mises Commented Oct 6, 2019 at 7:21
  • Yeh .. that works ... but i didnt get this "Remember that Observables are async " – Priyashan Jayasankha Commented Oct 6, 2019 at 7:46
  • Asynchronous check in dictionary ;] – Mises Commented Oct 6, 2019 at 9:50
  • Asynchronous just means that the order of the execution of each line is not guaranteed, in the sense that, whatever is inside the subscribe() handler is not guaranteed to happen before whatever es after its definition. In this particular case, outside of the subscribe() handler, there is no guarantee that this.showingEventList is indeed an array because it's assignment could happen afterwards, which is most likely what was happening. By moving your for loop inside, you're making sure to run it after this.showingEventList has been assigned. – moonstar-x Commented Aug 14, 2024 at 22:27
Add a ment  | 

2 Answers 2

Reset to default 0

You may need to pipe and map the information, as in the following code example (jump to (A)):

// posts.service.ts
import { Post } from './post.model';
import { map } from 'rxjs'; // =========================================== (B)

@Injectable({
  providedIn: 'root',
})
export class PostsService {
  private posts: Post[] = [];

// MORE CODE ...

/**
  * Method to get the list of posts from the server. It sends a GET request to
  * the server, retrieves the posts, and updates the local posts array. The
  * spread operator (...) creates a shallow copy of the posts array, ensuring
  * that the original array cannot be modified by the caller of this method.
  * @returns A copy of the posts array.
  */
getPosts() {
  // `...` makes a true copy of the posts
  /* return [...this.posts]; */
  this.http
    .get<{
      message: string;
      // Define here the posts[] typing
      posts: [{ title: string; content: string; _id: string }];
    }>('http://localhost:3000/api/posts')
    // =================================================================== (A)
    .pipe(
      map((postData) => {
        return postData.posts.map((post) => {
          return { title: post.title, content: post.content, id: post._id };
        });
      })
    )
    // =================================================================== (A)
    .subscribe((transformedPosts) => {
      this.posts = transformedPosts;
      // Emit the updated posts array
      this.postsUpdated.next([...this.posts]);
    });
}

// MORE CODE AND END OF FILE
}

Notice how the data is copied between lines (A). Notice where is map method ing from, in line (B).

// post.model.ts
export interface Post {
  id: string;
  title: string;
  content: string;
}

Possible reason:

The for loop is called before showingEventList is assigned with an array, i.e. before this.eventDetails.getOldEvents() emits the first event.

Put a check before the for loop:

if (Array.isArray(this.showingEventList)) {
  for ( const item  of this.showingEventList ) {
    this.clubs.push(item.club);
  }
}
发布评论

评论列表(0)

  1. 暂无评论