Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngFor is not updating List values in realtime in Angular

Tags:

angular

ngfor

I have added a component in a parent component. Child component gets data from server and shows it in a modal. Problem is that it is not updating data in realtime.

Here is html of child component:

<!--Permission MODAL-->
<div class="modal fade" id="transactionPermissionModal" role="dialog">
  <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
      <div class="modal-body">
        <p class="text-center">Create New</p>


          <div *ngFor="let permittedProfile of assignedPermissions" class="row">
            <div class="col-12">
              <p class="myText float-left">{{permittedProfile.profile.email}}({{permittedProfile.permission_type}})</p>
              <span style="float: right; cursor: pointer" (click)="RemovePermissionToUser(permittedProfile.profile.email)">&times;</span>
            </div>
          </div>

        <div class="row">
          <div class="col-7" style="padding-right: 0px;">
            <input type="text" style="border-right: none" class="new-transaction-textfield" placeholder="Invite Someone" id="permission-email">
          </div>
          <div class="col-3" style="padding-left: 0px;padding-right: 0px;">
            <select id="permission-dropdown" style="background-color: transparent; height: 32px; border: 1px solid #d9d9d9;border-left: none; outline: none">
              <option value="edit">can edit</option>
              <option value="view">can view</option>
            </select>
          </div>
          <div class="col-2" style="padding-left: 0px;">
            <button type="button" class="btn invite-btn" (click)="GivePermissionToUser()">Invite</button>
          </div>
        </div>

        <br />

      </div>
      <!--<div class="modal-footer">-->
      <button type="button" id="permission-modal-close-btn" data-dismiss="modal" style="display: none">Close</button>
      <!--</div>-->
    </div>

  </div>
</div>

here is that specific function which gets data and save it so that it should be visible on UI in realtime because of data binding

/**
   * Get permission list from server
   *
   * @param nextLink: link to retrieve a specific page/result_set
   * @param childIndex: index number if user has clicked any child of a transaction otherwise it 'll be null
   */
  GetPermissionsList(nextLink, childIndex: number = null) {

    if (nextLink === '') {
      this.assignedPermissions = [];
    }
    console.log(this.assignedPermissions);

    this.transactionsService.HandlePermissionRequestGeneracially(
      {}, this.url + nextLink, 'GET'
    ).subscribe((response) => {

      for (const entry of response.results) {
        this.assignedPermissions.push(entry);
      }

      this.shouldPermissionsVisible = true;
      console.log(this.assignedPermissions);

      const next = response.next;
      if (next !== null) {
        this.GetPermissionsList(next.substring(next.indexOf('?'), next.length), childIndex);
        return;
      }
    }, (error) => {
      this.snackbarHandler.showSnackBar('Error while getting permission');
    });
  }

Its getting correct data from server but problem is that it doesn't update it on UI right away. When first time it opens modal it shows no data but second time it shows result of first time. It means that it shows only old data saved not the one which it has retrieved from server.

I am calling GetPermissionList function like this:

const myThis = this;
    $('#transactionPermissionModal').on('shown.bs.modal', function (e) {
      myThis.GetPermissionsList('');
    });
like image 336
Zohab Ali Avatar asked May 06 '19 10:05

Zohab Ali


Video Answer


1 Answers

First, you should use Angular events instead of a query selector. Is there a good reason why you can't?

Second, as you say the console.log calls work correctly, it means that the member variable assignedPermissions is actually not modified in the correct object.

Which points to the real issue: the myThis thing does not work because the context of the call is not the right one in the callback. And it leads you to this kind of issue: How to access the correct `this` inside a callback?

Following this reasoning, here is the correct way to set your callback (which is, I repeat, not the Angular-way of doing):

$('#transactionPermissionModal').on('shown.bs.modal', (function (e) {
  this.GetPermissionsList('');
}).bind(this));

or

$('#transactionPermissionModal').on('shown.bs.modal', e => this.GetPermissionsList(''));
like image 96
Qortex Avatar answered Oct 28 '22 06:10

Qortex