Better way to test binding value changes than `setTimeout`?

Is there a better way to test binding than using setTimeout in the test case? Perhaps a way to trigger re-bind of the component explicitly?

it("dto change reflects in ViewModel change", async (done) => {
    await component.create(bootstrap);

    dto.pageNumber = 2;
    setTimeout(() => {
        expect(component.viewModel.pageNumber).toBe(2);
        done();
    }, 30);
});

Update:

I also noticed that simply changing dto does not trigger pageNumberChanged method. What would be work around to trigger it?

1 Like

If it’s a DTO, i guess you should use @observable instead of @bindable

My ViewModel has bindable properties, as I think it should, so I can bind values from surrounding view/view-model to it (ex: <paging page-number.bind="pageNumber"></paging>). So dto belongs to surrounding view, it is not view-model of component.

But observable/bindable topic does not address the question? Is there any way not to use setTimeout and to trigger pageNumberChanged(newValue, oldValue) method?

1 Like

@bindable callback is invoked asynchronously while @observable is not. @observable is best for DTO.

You can have a look at this simple comparison here Difference between @observable and @bindable

Yes, so I use @bindable because of number 4:

  1. Can be used to bind between custom elements

But, this is still a bit off the topic. My questions are:

  1. Is there any deterministic way to await for binding-update to happen, instead of setTimeout and random number of milliseconds? I do believe that this would be same for @observable and @bindable properties, right?
  2. Why is pageNumberChanged not triggered at all (synchronously or asynchronously)?

Note: As I said, dto is not internal to component’s VM, it’s data from wrapping custom element. In another example from Stackoverflow from Fred Kleuver, it was named bindingContext.