Caio Costa
Caio Costa

Reputation: 114

StencilJS's Watch decorator not firing with Array of Objects

I want to pass an array of objects as prop to my StencilJS component.

import { Watch, Prop} from '@stencil/core';


@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: false
})
export class MyComponent {

  @Prop({ mutable: true }) events: Array<Object>;

  @Watch('events')
  eventsChanged(newValue: any, oldValue: any) {
    if (oldValue != newValue)
        this.events = newValue;
  }

  render() {
    return (
      // my HTML
    );
  }
}

The HTML on my application:

<my-component ng-prop-events="$ctrl.events"></my-component>

My events array (declared in the controller of the above HTML):

events: Array<Object> = [{
  label: 'Cool event =)',
  startDate: new Date('2021/02/14'),
  endDate: new Date('2021/02/14')
}];

Whenever the user click in a checkbox, this events receives a new event:

  this.events.push(event);

I can see the event is indeed being pushed into events in the controller, but the @Watch decorator in StencilJS is never fired.

The component is receiving the events variable and I can see it in componentWillLoad().

What I have to do in order to make Watch observe the changes in my array?

Upvotes: 0

Views: 931

Answers (1)

Thomas
Thomas

Reputation: 8849

According to the Stencil Docs:

For arrays, the standard mutable array operations such as push() and unshift() won't trigger a component update. Instead, non-mutable array operators should be used as they return a copy of a new array. These include map() and filter(), and the ES6 spread operator syntax.

For example, to push a new item to an array, create a new array with the existing values and the new value at the end:

@State() items: string[];

// our original array
this.items = ['ionic', 'stencil', 'webcomponents'];

// update the array
this.items = [
  ...this.items,
  'awesomeness'
]

Upvotes: 2

Related Questions