# Multi observer property name

**URL:** <https://discourse.aurelia.io/t/multi-observer-property-name/4097>\
**Category:** Help Requests\
**Created:** [March 9, 2021, 12:02pm UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097 "2021-03-09T12:02:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mark](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/mark/32/2015_2.png) [@mark](https://discourse.aurelia.io/u/mark)\
**Post date:** [March 9, 2021, 12:02pm UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/1 "2021-03-09T12:02:25Z")

</div>

I’m using the multi observer pretty much the one described on the [blog](https://aurelia.io/blog/2015/4/3/aurelia-adaptive-binding/)

```
filter: any = {
  pageIndex: 0,
  pageSize: 25,
  query: '',
  orderColumn: 'name',
  orderDirection: 'asc'
};

constructor(private multiObserver: MultiObserver){
    this.multiObserver.observe(this.filter, Object.getOwnPropertyNames(this.filter), () => this.filterChanged(), []);
}

filterChanged(){
 // Get propertyname here which triggered the change.
  this.getApplicationList();
}

```

That’s all working fine, but I would really like to know which one of the properties is changed, since I have need to have different behavior when the pageIndex is changed then when all the other properties are changed. Is there a way to get the property name inside the filterChanged function? Hope that someone can help out.

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [March 9, 2021, 5:02pm UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/3 "2021-03-09T17:02:43Z")

</div>

You might want to take a look at the watch decorator [Better know a framework #27: using watch decorator - #12 by bigopon](https://discourse.aurelia.io/t/better-know-a-framework-27-using-watch-decorator/3762/12)

---

<div class="post-metadata">

**Author:** ![mark](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/mark/32/2015_2.png) [@mark](https://discourse.aurelia.io/u/mark)\
**Post date:** [March 10, 2021, 7:37am UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/4 "2021-03-10T07:37:46Z")

</div>

Thanks for the suggestion. I did look at the watch decorator, but it seems it’s not supporting array changes. I know that’s not in my example 😇, can anybody suggest another option.

I can always create a separate observer for the page index and handle it like this for instance:

```
this.multiObserver.observe(this.filter, Object.getOwnPropertyNames(this.filter), () => this.filterChanged(false), [
  'pageIndex'
]);
this.multiObserver.observe(this.filter, ['pageIndex'], () => this.filterChanged(true));

```

But I have a lot of pages with this functionality (all of them with a different set of filters), so trying to keep it as simple as possible.

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [March 10, 2021, 9:27am UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/5 "2021-03-10T09:27:52Z")

</div>

@bigopon is Array watching perhaps a future usecase for the watch deco?

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [March 10, 2021, 10:21am UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/6 "2021-03-10T10:21:46Z")

</div>

In the example here

```auto
this.multiObserver.observe(this.filter, Object.getOwnPropertyNames(this.filter), () => this.filterChanged(false), [
  'pageIndex'
]);
this.multiObserver.observe(this.filter, ['pageIndex'], () => this.filterChanged(true));

```

There doesn’t seem to be any array? If that’s the case, maybe can you clarify it a bit @mark

---

<div class="post-metadata">

**Author:** ![mark](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/mark/32/2015_2.png) [@mark](https://discourse.aurelia.io/u/mark)\
**Post date:** [March 10, 2021, 10:30am UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/7 "2021-03-10T10:30:52Z")

</div>

Sure I can, I tried to kept the sample as simple as possible, that’s why I didn’t include the array. But I have pages with filters like this:

```
filter: ProductListFilter = {
    pageIndex: 0,
    pageSize: 25,
    query: '',
    orderColumn: 'createdDate',
    orderDirection: 'desc',
    suppliers: [],
    categories: [],
    tags:[]
};

```

I modified the observer to have a array of properties to exclude (which in practice at the moment is used for pageIndex only)

`observe(object: any, properties: string[], callback: any, excludedProperties: string[] = []): Observer`

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [March 10, 2021, 11:10am UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/8 "2021-03-10T11:10:15Z")

</div>

You can use the binding engine directly to observe an expression, so that you can automatically watch a property on an object, and optionally watch the length property of the sub object, which roughly equals to observing the array. An example here [https://gist.dumber.app/?gist=d47cc594e7adf3f46548d9d1aaa8e2b2](https://gist.dumber.app/?gist=d47cc594e7adf3f46548d9d1aaa8e2b2)

---

<div class="post-metadata">

**Author:** ![mark](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/mark/32/2015_2.png) [@mark](https://discourse.aurelia.io/u/mark)\
**Post date:** [March 10, 2021, 12:45pm UTC](https://discourse.aurelia.io/t/multi-observer-property-name/4097/9 "2021-03-10T12:45:27Z")

</div>

Thank you very much @bigopon for your example 🤩 I implemented it like below. It also got some of your binding-ext.js sample with the taskqueue, which I also need when clearing multiple filters.

Not sure whether I should use the collectionObserver or the expressionObserver, but both options work the way I want to.

```auto
@autoinject
export class AnotherObserver {
  constructor(private bindingEngine: BindingEngine, private taskQueue: TaskQueue) {}

  observe(object: any, callback: (this: void, e: string) => void): Observer {
    let isCallbackQueued = false;

    const unmarkQueued = () => {
      isCallbackQueued = false;
    };

    const subscriptions = Object.keys(object).map((prop) => {
      const property = object[prop];
      let observer: any;
      if (Array.isArray(property)) {
        observer = this.bindingEngine.collectionObserver(object[prop]);
      } else {
        observer = this.bindingEngine.propertyObserver(object, prop);
      }

      return observer.subscribe(() => {
        if (!isCallbackQueued) {
          this.taskQueue.queueMicroTask(unmarkQueued);
          this.taskQueue.queueMicroTask(() => callback(prop));
          isCallbackQueued = true;
        }
      });
    });

    return {
      dispose: () => {
        while (subscriptions.length) {
          subscriptions.pop()();
        }
      }
    };
  }
}

```
