1

In the component I have a simple table were one of the columns calls a function getOrderItems() to get order corresponding items:

<p-table
  [value]="orders$()"
  [tableStyle]="{ 'min-width': '50rem', 'margin-top': '16px' }"
>
  <ng-template pTemplate="header">
    <tr>
      <th>Id</th>
      <th>Contact</th>
      <th>Total</th>
      <th>Status</th>
      <th>Item</th>
    </tr>
  </ng-template>
  <ng-template pTemplate="body" let-order>
    <tr>
      <td>{{ order.id }}</td>
      <td>{{ order.contact }}</td>
      <td>{{ order.total }}</td>
      <td>{{ order.status }}</td>
      <td>{{ getOrderItems() }}</td>
    </tr>
  </ng-template>
</p-table>

Here is the getOrderItems() function:

getOrderItems() {
    const orderItems = this.ordersService.orderItems();

    console.log(orderItems);
    return orderItems;
  }

Finallt here is the function inside ordersService:

orderItems() {
    let orderItems: OrderItem[] = [];
    this.databaseService
      .getDatabase()
      .orderItem.find()
      .exec()
      .then((doc) => {
        orderItems.push(doc);
      })
      .catch((e: RxError) => {
        return Promise.reject(
          'Error while looking for order items: ' + e.message,
        );
      });

    return orderItems;
  }

The issue I'm getting infinite loop because of getOrderItems() function and I have no idea why?

1

1 Answer 1

0

Remove the method getOrderItems from the HTML, since methods inside HTML get called for each change detection cycle, so it gets called a lot of times, hence you are getting this error.

  <ng-template pTemplate="body" let-order>
    <tr>
      <td>{{ order.id }}</td>
      <td>{{ order.contact }}</td>
      <td>{{ order.total }}</td>
      <td>{{ order.status }}</td>
    </tr>

After this you should ensure you always return either a promise or an observable, do not return any code, below the promise code, this is because the promise code is asynchronous and the return code is synchronous, hence, we should be careful here, because the function will return the array before items are even pushed to the array.

Promise approach:

  orderItems() {
    return this.databaseService
      .getDatabase()
      .orderItem.find()
      .exec()
      .then((doc) => {
        orderItems.push(doc);
      })
      .catch((e: RxError) => {
        return Promise.reject(
          'Error while looking for order items: ' + e.message,
        );
      });
  }

Here we return the promise, we can use then to get the data inside the component, we leave the catch as is, so that the same can be reused in many places.

Now, we use then to get the data from the promise returned.

export class SomeComponent {
  orderItems: OrderItem[] = [];

  getOrderItems() {
    const orderItems = this.ordersService.orderItems().then((response: any) => {

    this.orderItems.add(response);
    });
  }

Now you can bind this data to HTML like so:

  <ng-template pTemplate="body" let-order>
    <tr>
      <td>{{ order.id }}</td>
      <td>{{ order.contact }}</td>
      <td>{{ order.total }}</td>
      <td>{{ order.status }}</td>
      <td>{{ orderItems | json }}</td>
    </tr>
  </ng-template>

We use json pipe to print the data in a readable format, we should use some HTML to display the data properly.

Sign up to request clarification or add additional context in comments.

Comments

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.