3

First question ever on StackOverflow, how exciting!

Currently I have two custom components, both accepting a couple of input variables :

<sod-matrix-table #matrix 
  [entities]="entities" 
  [pairs]="pairs" 
  [displayedColumns]="displayedColumns">
</sod-matrix-table>

and :

<data-table 
  #table 
  [type]="sodMatrixQuery.targetType" 
  [query]="sodMatrixQuery" >
</data-table>

When updating the entities, pairs or columns of the first tag, everything updates correctly. For example, when I update the displayedColumns array in a component that uses the matrix table tag, the table inside of that component gets updated with the desired columns.
However, when I update the sodMatrixQuery in the component, and press the search button, the query object of the data-table isn't updated correctly, although they are bound together.

Example:

data-table has a field query and uses this query to send REST requests to the server. SODMatrixComponent has a field sodMatrixQuery and uses the tag of the data-table, binding his field to the other field.

An SOD Matrix contains pairs of objects. When I select 2 pairs, and press the search button, the data-table sends the REST request with 2 pairs. However, when I remove the two pairs, and press search again, the data-table component sends another REST request, again with 2 pairs instead of none. When pressing the search button a second time, the correct request is send.

I debugged and internally everything with the pairs goes fine, it's only the databinding that doesn't get updated in time. Any thoughts about this?

EDIT: This is the code that happens on the button click:

public search() {
    const tempQuery = new SODMatrixQuery(this.lhsType, this.rhsType, [], this.entities);

    // Only look at elements above the diagonal
    for (let i = 1; i < this.pairs.length; i++) {
        for (let j = 0; j < i; j++ ) {
            const p = this.pairs[i][j];
            if (p.checked) {
                tempQuery.addToxicPair(p);
            }
        }
    }

    if (this.dataTable) {
        this.sodMatrixQuery = tempQuery;
        // this.dataTable.query = tempQuery;
        this.dataTable.loadDataPage();
    }

}

SODMatrixComponent variables :

@ViewChild("table")
public dataTable: ElimityDataTableComponent;

public sodMatrixQuery: SODMatrixQuery;

Datatable component :

@Input()
public query: Query;

SODMatrixQuery extends Query!

The commented line below is a fix, to update the query object directly, but I'm just curious why the databinding doesn't work.

10
  • What is the change detection strategy of your components? Have you checked this out yet: netbasal.com/… ? Commented Aug 10, 2018 at 8:31
  • How are you updating the sodMatrixQuery? Commented Aug 10, 2018 at 8:36
  • @AgashThamo. I haven't really set a particular strategy, so I guess it's the default? I just find it weird it works with one tag, and not with the other Commented Aug 10, 2018 at 8:36
  • @rinukkusu Updating my post now with more code! Commented Aug 10, 2018 at 8:38
  • Should be the default if you are not extending anything. If one of the @Inputs is an object or an array, Angular will not detect changes if you change values within the object or the array, since it will compare the references, which will stay the same. Edit: Is it possible for you to create a basic stackblitz and recreate your problem? Commented Aug 10, 2018 at 8:39

1 Answer 1

2

Looks like change detection would need a moment to breathe there - the databinding can't be updated between the setting of the sodMatrixQuery member and the this.dataTable.loadDataPage() call - that's why it still has the old value on the first call. After that change detection will be run and on the second call it will have the right values.

if (this.dataTable) {
    this.sodMatrixQuery = tempQuery;
    // can't update the bindings here
    this.dataTable.loadDataPage();
}

So looking at your current architecture, it would be better to move the loadDataPage() call to the dataTable component into the OnChanges lifecycle hook, like Agash said in the comments.

export class ElimityDataTableComponent implements OnChanges {
  // ...
  ngOnChanges(changes: SimpleChanges) {
    if (changes.query) {
      this.loadDataPage();
    }
  }

This way, every time you update the sodMatrixQuery, it automatically loads the new data.

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.