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 ????
- 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 thesubscribe()
handler, there is no guarantee thatthis.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 afterthis.showingEventList
has been assigned. – moonstar-x Commented Aug 14, 2024 at 22:27
2 Answers
Reset to default 0You 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);
}
}