6

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('');
    });
Zohab Ali
  • 8,426
  • 4
  • 55
  • 63
  • Can you please post the results of your `console.log` calls? Are you sure your function is called twice? – Qortex May 06 '19 at 11:14
  • @Mic yes its showing correct data in results of console.log.....empty list in first answer and list with all entries, which retrieved from server, in second answer – Zohab Ali May 06 '19 at 11:20
  • @ZohabAli why you are not using async to archive this? :) – Yash Rami May 06 '19 at 11:22
  • @YashRami I am trying your solution right now. I ll let you know – Zohab Ali May 06 '19 at 11:24
  • Then it should work. It means that the `myThis` trick does not work and you are not modifying the right member variable. Why do you use that instead of regular Angular events? – Qortex May 06 '19 at 11:41
  • @Mic I want to call this function only when modal popups. That is why I am using it, and its calling function at right time – Zohab Ali May 06 '19 at 11:43
  • @Mic actually you are right. If I dont call function from within Jquery function then it shows data as expected. If you write this as answer then I can accept it – Zohab Ali May 06 '19 at 11:46
  • Yes, and I pointed to the underlying javascript reason in my answer. You should prefer Angular event: start this callback on the `(click)` or whatever event, and you don't have to worry about that. – Qortex May 06 '19 at 11:48

1 Answers1

3

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(''));
Qortex
  • 7,087
  • 3
  • 42
  • 59
  • Genius! Thanks for all the help. You are right that I should use Angular events. Although jquery methods are not working right now for me which you have suggested. So I am gonna try some other way. But thanks for helping me find the problem :) – Zohab Ali May 06 '19 at 11:54
  • 1
    @Mic Great Answer :) – Yash Rami May 06 '19 at 11:55