1

While creating a custom widget for visualizing dynamic table data, I encountered some issues and would like to share a minimal working example to illustrate the problem.

JS:

self.ctx.$scope.showAlert = function() {
window.alert("my device");
};

self.ctx.$scope.var = [
"id: 1, name: 'Batch A'",
"id: 2, name: 'Batch B'"
];

self.ctx.$scope.datasourceData = [];

self.ctx.detectChanges();
};

HTML:

<div class="mainCard">
<h3>Hello World</h3>
<button mat-raised-button color="primary" (click)="showAlert()">Click me</button>

<p>{{ctx.$scope.var}}</p>

<ul>
<li ng-repeat="item in ctx.$scope.var">
Wert: {{item}}
</li>
</ul>

<h3>Einzelne Werte</h3>
<p>Erster Wert: {{ctx.$scope.var}}</p>
</div>

What works:

  • The alert button (showAlert) works correctly.
  • Displaying the entire array ({{ctx.$scope.var}}) also works.

Problems:

  • Accessing array items directly (e.g. {{ctx.$scope.var[1]}}) throws an error: "Widget Error: can't access property 1, ctx.ctx.$scope.var is undefined" -ng-repeat does not render any list items, although the array is initialized as expected in onInit.

Is there a recommended way to bind and access dynamic arrays within ThingsBoard widgets—especially when aiming to use ng-repeat or direct indexing?

0

1 Answer 1

0

Looks like you are using ng-repeat which is from Angular - 1.x.x, but you are using Angular 2+ in your application. You need to use *ngFor or @for( available in the latest angular versions).

<ul>
  <li *ngFor=" let item of ctx.$scope.var">
    Wert: {{item}}
  </li>
</ul>

Using @for:

<ul>
 <!-- or ;track $index -->
  @for(item of ctx.$scope.var; track item) {
    <li>
      Wert: {{item}}
    </li>
  }
</ul>
Sign up to request clarification or add additional context in comments.

2 Comments

hi, thanks for your fast reply. If I use your second option I get: "Widget wasn't loaded due to the following errors: Failed to compile widget html. Error: Errors during JIT compilation of template for : @for loop must have a "track" expression (" <ul> [ERROR ->]@for(item of ctx.$scope.var) { <li> Wert: {{item}} "): ng:////template.html@5:10" However, using *ngFor did the trick! Thanks a lot. I was trying to figure it out with ChatGPT for hours :D
@OmnivoreRecycling updated my answer for \@for, my mistake

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.