Angular - Constructor item is "undefined" in function

1.2k views Asked by At

I'm trying to use my data service in a component, but when I click the button it gives error and says data service is undefined.

Here's my component file:

export class ProductsComponent implements OnInit {
  dataSource: any;
  priority: any[];
  e: any;

  constructor(public dataService: DataService) {
      // data source stuff...
  }

  ngOnInit() {
    console.log(this.dataService) //successfully shows DataService object
  }

  addToCart(e) {
    console.log(e.row.data["Task_Subject"]);
    console.log(this.dataService) // undefined?!?
    this.dataService.addItem(e.row.data["Task_Subject"])
  }
}

And the HTML Template of Component:

<h2 class="content-block">Products</h2>

<dx-data-grid class="dx-card wide-card" [dataSource]="dataSource" [showBorders]="false" [focusedRowEnabled]="true"
  [focusedRowIndex]="0" [columnAutoWidth]="true" [columnHidingEnabled]="true">

  <dxo-paging [pageSize]="10"></dxo-paging>
  <dxo-pager [showPageSizeSelector]="false" [showInfo]="true"></dxo-pager>
  <dxo-filter-row [visible]="true"></dxo-filter-row>

  <dxi-column dataField="Task_ID" [width]="90" [hidingPriority]="2">
  </dxi-column>
  <dxi-column dataField="Task_Subject" [width]="190" caption="Subject" [hidingPriority]="8">
  </dxi-column>
  <dxi-column dataField="Task_Status" caption="Status" [hidingPriority]="6">
  </dxi-column>
  <dxi-column dataField="Task_Priority" caption="Priority" [hidingPriority]="5">
    <dxo-lookup [dataSource]="priority" valueExpr="value" displayExpr="name">
    </dxo-lookup>
  </dxi-column>
  <dxi-column dataField="ResponsibleEmployee.Employee_Full_Name" caption="Assigned To" [allowSorting]="false"
    [hidingPriority]="7">
  </dxi-column>
  <dxi-column caption="Actions" type="buttons" [hidingPriority]="0">
    <dxi-button icon="plus" [onClick]="addToCart">Action</dxi-button>
  </dxi-column>
</dx-data-grid>

When I click the button on 'dxi-button' addToCart() function runs. In ngOnInit function, the data service shows up, but in addToCart function, console logging data service gives me undefined.

What am I doing wrong? I'm using DevExtreme by the way.

3

There are 3 answers

0
Jason Goemaat On

Looking at the callback function docs for devextreme components, the binding is done in a very un-angular way.

In angular and for top-level components you can use the () binding. Since nested components use the [] binding syntax, you need to pass it a function that is bound to the object you wish to be 'this' inside the function. It recommends doing that in your constructor:

Callback functions are executed outside the component's context. If the context is important, explicitly bind the callback function to it in the constructor.

  constructor(public dataService: DataService) {
      // data source stuff...
      this.addToCart.bind(this);
  }
3
Alann On

I think the way you call your function isn't in the angular context

Try to do a console.log(this) and if the object isn't of type ProductsComponent then you aren't in the angular context anymore

If that's the case you can change the way you call the onClick function inside your html template

maybe something like

(onClick)="addToCart(item)"
0
Mert Can Bilgiç On

I fixed with a little trick, posting the answer for another people. Devexpress change the scope of "this". For solving that, I just added

this.addToCart = this.addToCart.bind(this);

into constructor and now I can use this.dataService properly! Thank you for your help guys.