Daire
Daire

Reputation: 45

Trying to display an array using a *ngFor loop

I grouped a data array using lodash and can see the output in my console, but my *ngFor loops don't display the data on my html page. Can anyone point out what I'm missing here?

app.component.ts:

export class AppComponent {
  name = "Angular";

  data = [
    {
      customer: {
        name: "John"
      },
      transaction_date: "2017-04-18"
    },
    {
      customer: {
        name: "Dick"
      },
      transaction_date: "2017-06-30"
    },
    {
      customer: {
        name: "Harry"
      },
      transaction_date: "2017-04-03"
    },
    {
      customer: {
        name: "John"
      },
      transaction_date: "2017-05-03"
    }
  ];

  constructor() {}

  ngOnInit() {
    // Sort by Month

    // Format month
    const monthName = item =>
      moment(item.transaction_date, "YYYY-MM-DD").format("MMM");

// Establish groupBy array
    const byMonth = _.chain(this.data)
      .groupBy(monthName)
      .mapValues(items => _.map(items, "customer.name"))
      .value();
    console.log(byMonth);
    return byMonth;
    console.log(monthName);

    // By Day
    const dayName = item =>
      moment(item.transaction_date, "YYYY-MM-DD").format("DD");

    const byDay = _.chain(this.data)
      .groupBy(dayName)
      .mapValues(items => _.map(items, "customer.name"))
      .value();
    console.log(byDay);
    return byDay;
  }
}

app.component.html

<table *ngFor="let month of months">
    <tr>
        <th>{{month.month}}</th>
    </tr>
    <tr>
        <td>
            <table *ngFor="let customer of customers">
                <tr>
                    <td>
                        {{customer.name}}
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

Desired HTML Format (in a table but the formatting wasn't supported):

Thanks guys! :)

Upvotes: 0

Views: 912

Answers (1)

Narm
Narm

Reputation: 10864

There are a few mistakes, but you're close.

1) You need to declare a public property in your component that will be used to loop through. Notice how I created public myData.

2) You then need to initialize that object with the data you want to display. In your original code you were trying to do a return from the ngOnInit. That is not what you want to do. You want to assign that data to your public property myData

3) You have to recognize Angular ngFor does not want to loop through anything that is not an array by default. Lucky for you since Angular version 6 they provided support to loop over objects. However, in order to accomplish that you need to include the new pipe | keyvalue.

Working StackBlitz Demo

export class AppComponent {
  name = "Angular";

  public myData = {};

  data = [
    {
      customer: {
        name: "John"
      },
      transaction_date: "2017-04-18"
    },
    {
      customer: {
        name: "Dick"
      },
      transaction_date: "2017-06-30"
    },
    {
      customer: {
        name: "Harry"
      },
      transaction_date: "2017-04-03"
    },
    {
      customer: {
        name: "John"
      },
      transaction_date: "2017-05-03"
    }
  ];

  constructor() {}

  ngOnInit() {
    // Sort by Month

    // Format month
    const monthName = item =>
      moment(item.transaction_date, "YYYY-MM-DD").format("MMM");

    // Establish groupBy array
    this.myData = _.chain(this.data)
      .groupBy(monthName)
      .mapValues(items => _.map(items, "customer.name"))
      .value();
    console.log(this.myData);
  }
}

HTML

<table *ngFor="let data of myData | keyvalue">
    <tr>
        <th>{{data.key}}</th>
    </tr>
    <tr>
        <td>
            <table *ngFor="let customer of data.value">
                <tr>
                    <td>
                        {{customer}}
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

Upvotes: 1

Related Questions