0

I am fetching the courses from the Firebase database as so:

              this.fetchItems()
              .subscribe((res) => {
                   this.coursesFiltered = res.filter((filtered: any) => {
                    return filtered.courseStatus === 2 || filtered.courseStatus === 3
                   });


               });

The function fetchItems()

  fetchItems() {
    return this.afDB.list('courses', (ref) => ref.orderByChild('courseSemCode'))
       .snapshotChanges()
       .map((arr) => {
          return arr.map((snap: any) => {
            return snap.status = snap.payload.val();
          });
        });
      }

Then I want to group them by courseSemCode so that it displays properly in the cards

<ion-card *ngFor="let item of coursesFiltered | groupBy:'courseSemCode'">
    <ion-card-header>
      <h6>{{item.courseSemester + " " + item.courseYear}}</h6>
    </ion-card-header>

    <ion-card-content>

        <ion-list>
            <button ion-button class="text" class="btnCourse">
              {{item.courseName}}
            </button>
        </ion-list>
    </ion-card-content>
  </ion-card>

The groupBy pipe is a custom pipe that I got from this thread: How to group data in Angular 2?

Which is this:

    @Pipe({name: 'groupBy'})
export class GroupByPipe implements PipeTransform {
  transform(value: Array<any>, field: string): Array<any> 
{
  if(!value || !value.length) { 
    return value; 
  }else{
    const groupedObj = value.reduce((prev, cur)=> {
      if(!prev[cur[field]]) {
        prev[cur[field]] = [cur];
      } else {
        prev[cur[field]].push(cur);
      }
      return prev;
    }, {});
    return Object.keys(groupedObj).map(key => ({ key, value: groupedObj[key] }));
  }
  }  
}

But unfortunately in the end I'm faced with the problem TypeError: Cannot read property 'reduce' of undefined

I believe this has to do with the .subscribe which I've written in the constuctor, which only means that the coursesFiltered still has no data.

How can I make sure it does and solve this issue?

Thank you

3
  • Are you using the async pipe to display data, or are you using a variable ? Commented Mar 20, 2018 at 14:08
  • @trichetriche I'm only using groupBy as pipe Commented Mar 20, 2018 at 14:10
  • okay, then see my answer ! Commented Mar 20, 2018 at 14:11

2 Answers 2

2

I think it is failing when it is evaluating before coursesFiltered is set. Maybe initialise coursesFiltered to an empty array.

this.coursesFiltered: any[] = [];
Sign up to request clarification or add additional context in comments.

1 Comment

It did help me display the app without errors but everything is showing "undefined".
0

In your pipe, you can simply test for it :

transform(value: any, args?: any) {
  if(!value || !value.length) { return value; }
  return value.reduce(...);
}

EDIT In your loop you do this

*ngFor="let item of coursesFiltered | groupBy:'courseSemCode'"

But your structure for the grouped array is this

[{key: 'your key', value: [...]}]

This means that you have to make two loops :

<ion-card *ngFor="let group of coursesFiltered | groupBy:'courseSemCode'">
  <ng-container *ngFor="let item of group.value">
    <ion-card-header>
      <h6>{{item.courseSemester + " " + item.courseYear}}</h6>
    </ion-card-header>

    <ion-card-content>

        <ion-list>
            <button ion-button class="text" class="btnCourse">
              {{item.courseName}}
            </button>
        </ion-list>
    </ion-card-content>
  </ng-container>
</ion-card>

4 Comments

It also did help remove the error, but I only see "undefined" now where the proper values should be.
A lot of undefined or only just one ?
All of the fields where "item." they all show undefined
Then your pipe isn't working. Could you share your pipe code ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.