Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Observing getter property results in TypeError: context is not a function #252

Closed
NateRedding opened this issue Dec 3, 2015 · 13 comments
Closed

Comments

@NateRedding
Copy link

I have a custom attribute class that has a @bindable property that I would like to watch for changes. I use the BindingEngine to create a PropertyObserver and use that to subscribe to the property in question. When the property changes, I get the following error:

Uncaught TypeError: context is not a function 
callSubscribers @ aurelia-binding.js:244
call @ aurelia-binding.js:3221
flushMicroTaskQueue @ aurelia-task-queue.js:110
(anonymous function) @ aurelia-task-queue.js:60

Here are some code snippets... some code removed for conciseness:

@customAttribute('some-widget')
export class SomeWidget {
  @bindable readOnly = false;

  attached() {
    this.bindingEngine.propertyObserver(this, 'readOnly').subscribe((readOnly) => {
      ...
    });
  }
}
  <textarea some-widget="read-only.one-way: isArchived"></textarea>

The exact same code works without issue if remove the @bindable property and just create the property on 'this'. Obviously, I don't get the value of 'readOnly' that I am binding to in the parent in that case, however.

@EisenbergEffect
Copy link
Contributor

With bindables, you just create a method on your class to get the change callbacks. In this case readOnlyChanged. Is there some reason you can't do that?

@EisenbergEffect
Copy link
Contributor

Example

@customAttribute('some-widget')
export class SomeWidget {
  @bindable readOnly = false;

  readOnlyChanged(newValue, oldValue) {
    //do stuff here...
  }
}

@NateRedding NateRedding changed the title Observing @bindable property results in TypeError: context is not a function Observing getter property results in TypeError: context is not a function Dec 3, 2015
@NateRedding
Copy link
Author

Of course, as soon as I posted this I figured something new out... the problem isn't with @bindable, so much as it is with the property on my view that I am binding to being a getter. Is that going to be supported in the future?

I will also try your suggestion... I am modifying someone else's code and forgot about that feature.

@NateRedding
Copy link
Author

I do get the same error with the getter and using readOnlyChanged().

@EisenbergEffect
Copy link
Contributor

Getter? I don't understand what you mean by that.

@EisenbergEffect
Copy link
Contributor

I need to see an example that is more representative of what you are actually doing. You can observe getters but you cannot use the @bindable decorator on a getter because that decorator generates a getter and a setter and expects a particular usage pattern.

@NateRedding
Copy link
Author

Yep - no problem. My parent view model has this:

  get isArchived() {
    return this.newsItem.status === 'archived';
  }

I am able to bind to this in other places in my view, but when I do it for my custom attribute, I get the above error.

So, for instance, this works:

    <fieldset disabled.one-way="isArchived">

but this results in an error:

  <textarea some-widget="read-only.one-way: isArchived"></textarea>

I see why you are saying it doesn't work - because @bindable is generating it's own getter and setter. Seems a little inconsistent though.

@NateRedding
Copy link
Author

FYI - I got it working in my case by not using the getter and binding to an expression:

  <textarea some-widget="read-only.one-way: newsItem.status === 'archived'"></textarea>

But I was hoping the getter would clean up my template a bit.

@EisenbergEffect
Copy link
Contributor

You should not be getting the error with the above code. Can you create a repro on the skeleton-navigation so I can see the error and track it down?

@NateRedding
Copy link
Author

Yep - I will try to do so later tonight or tomorrow.

@NateRedding
Copy link
Author

@EisenbergEffect Of course I have not been able to reproduce this off of the skeleton project. But, I did figure out that it if I don't use 'aurelia-computed' in my application, then I do not get the error. (I still can't reproduce it yet in the skeleton app even with 'aurelia-computed' added.) So, it is likely something else we are doing wrong in combination with a bug in 'aurelia-computed' of some sort. Thanks for the help - and sorry for creating an issue prematurely! I will create an issue for aurelia-computed if I can ever narrow it down any more.

@pfurini
Copy link

pfurini commented Dec 10, 2015

Hi
I'm experiencing the same problem.. I don't have time to to create a repro, but I nailed down the problem in the aurelia-binding.js code.

The problem seems to be in the callSubscriber function, when there is a large amount of computed properties depending on the value of another view model property, thus resulting in deep nested calls.

The last for loop in the function set tempContextsRest[i] = null and tempCallablesRest[i] = null, but when the method returns as part of a nested call, the outer function continues executing with these values emptied, and the context variable ends up being null.

Hope it can help identify the source of the problem..

EDIT: obviously one can simply add a if (context) check before calling context(...), but I don't know which other side effects this bug have on the binding process..

EDIT 2: I can confirm that this bug is related to the computedFrom attribute. When I remove some of these attributes from my view model, the error disappears. It's not a specific one, just random combinations of them. It seems that reducing the number of computedFrom attributes, that are tied to the same property, under 3 does the trick, but it definitely needs more investigations..

@EisenbergEffect
Copy link
Contributor

@jdanyow There's some new information here reported by @Nexbit Can you take a look at this after we get your new optimizations merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants