TypeError with popups (MVC App)

edited October 2013 in Enyo 2.4
Hi,

I'm trying to use a popup in my app, but after declaring it, it throws the following error:
Uncaught TypeError: Object function () {
			var FinalCtor;
			// check for cached final constructor first, used mainly when
			// developers directly use kind names in their components instead of
			// strings that are resolved at runtime.
			if (DeferredCtor._FinalCtor) {
				FinalCtor = DeferredCtor._FinalCtor;
			} else {
				if (!(this instanceof DeferredCtor)) {
					throw "enyo.kind: constructor called directly, not using 'new'";
				}
				FinalCtor = DeferredCtor._finishKindCreation();
			}
			var obj = enyo.delegate(FinalCtor.prototype);
			var retVal = FinalCtor.apply(obj, arguments);
			return retVal? retVal: obj;
		} has no method 'subclass'
Popup demos in the samples folder work perfectly using the same version of enyo and onyx.

Comments

  • Since you're seeing deferred code, you're using a version of Enyo master branch. Can you provide a reproduction case in jsfiddle for this? This could be showing a problem with that optimization, but it might be a user error too, and without the actual declaration, I won't know.
  • I can't post the code here, sadly, but I will try to make a fiddle that could show this behavior. It's not easy, because I know the Popup declaration is done right (it fails too when I copy a Sampler's Popup into the components array in my view).
  • edited October 2013
    What this means is that some parent kind hasn't been undeferred yet. The subclass call is done via a kind feature in Oop.js where Enyo's code walks up the prototype chain, calling subclass on each base.

    I just went over the code that sets that base property, and it's always a direct kind reference, produced by a call to enyo.constructorForKind() which will undef anything passed in. So, having some .base reference to a deferred kind is very puzzling to me.

    Maybe this could happen if you redefine a kind after its been used, but even then, I that shouldn't alter the base reference that's already been established.

    As a work around, you can also turn off deferral globally by adding the line
    <script> window.enyo = { options: { noDefer: true } }; </script>
    
    in your index.html before you include enyo.js. However, I'd really like to understand why this is happening for you.
  • edited October 2013
    @unwiredben, the problem comes from using enyo.registerTheme(). I was using it to avoid having to name every onyx component, and it seems that the new deferred code doesn't play nicely with that feature at application view level.
  • Ah, that makes some sense. We've never done any testing with enyo.registerTheme in the 2.3 development tree, since it was a bit of a failed experiment. I'll try some things and see if I can reproduce the bug now.
  • @unwiredben It's easy to reproduce, if you define an enyo.Application with a view.

    For that view, any onyx component you add will fail (in fact, any component "path" string, like "enyo.Button"). For child kinds defined _outside_ of that view (I mean using enyo.kind()) everything works as expected.
  • oh, good data point... does that happen even if you don't use enyo.registerTheme()?
  • edited October 2013
    No, only if you use enyo.registerTheme(). Without calling it, everything works as expected.

    Sadly, because I find registerTheme() pretty useful to save some characters. In fact, I think it should be called automatically when loading onyx. It's cool to have everything onyxified (or whateverfied) with just a a single line.

    Seems like the application view components are the only ones ones that get instantiated before undeferred.
  • edited October 2013
    Try changing ViewController.js -- in the viewChanged method,
    if (typeof this.viewKind == "string") {
    	this.viewKind = enyo.getPath(this.viewKind);
    }
    
    into
    if (typeof this.viewKind == "string") {
    	this.viewKind = enyo.constructorForKind(this.viewKind);
    }
    I bet that will fix it.
  • edited October 2013
    I made a reproduction at http://jsfiddle.net/EA99b/1/, and a fix should be in tonight.

    The problem ended up being an unintentional recursion with onyx.Popup. The kind was specified with a base of just "Popup", not "enyo.Popup". This meant that when the OOP code tried to undefer onyx.Popup, it found the base name on the registered theme, so make the in-process onyx.Popup the base of itself. That's bad.

    Forget changing ViewController... the real fix is in Popup.js in onyx, changing kind: "Popup" to kind: "enyo.Popup".

    (Code change reviewed and pulled at https://github.com/enyojs/onyx/pull/181)
  • Thanks, @unwiredben, and sorry for the delay in posting. hard work here... with Enyo, of course.
Sign In or Register to comment.