onsenui and jaydata doesn't coexist

80 Views Asked by At

when using this order :

<script src="lib/angular/angular.js"></script>
<script src="lib/onsen/js/onsenui.js"></script>
<script src="http://include.jaydata.org/datajs-1.0.3.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/jaydatamodules/angular.js"></script>

I get this error

TypeError: Class.extend is not a function  
    at Object.<anonymous> (onsenui.js:13049)  
    at Object.invoke (angular.js:4535)  
    at Object.enforcedReturnValue [as $get] (angular.js:4387)  
    at Object.invoke (angular.js:4535)  
    at angular.js:4352  
    at getService (angular.js:4494)  
    at Object.invoke (angular.js:4526)  
    at Object.enforcedReturnValue [as $get] (angular.js:4387)  
    at Object.invoke (angular.js:4535)  
    at angular.js:4352

And when using this order:

<script src="lib/angular/angular.js"></script>
<script src="http://include.jaydata.org/datajs-1.0.3.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/jaydatamodules/angular.js"></script>
<script src="lib/onsen/js/onsenui.js"></script>

note: edited to correct the order

jaydata.js:3342 Uncaught TypeError: Cannot read property 'apply' of undefined

any help is appreciated!

2

There are 2 best solutions below

0
Hicham Taoufikallah On BEST ANSWER

Finally I found a solution based on Ilia Yatchev answer so thanks to him.

first I used the downloaded jaydata files instead of the online files since it contains the code change that Ilia Yatchev mentionned on his answer

var Class;
$data.Class = Class = new ClassEngineBase();

note : the order isn't a problem now

<script src="scripts/platformOverrides.js"></script>
<script src="lib/angular/angular.js"></script>
<script src="lib/onsen/js/onsenui.js"></script>
<script src="lib/datajs-1.0.3.js"></script>
<script src="lib/jaydata.js"></script>
<script src="lib/jaydatamodules/angular.js"></script>

then in the code we save a reference of the created entity:

var Todo = $data.Entity.extend("Todo", {
    Id: { type: "int", key: true, computed: true },
    Task: { type: String, required: true, maxLength: 200 },
    DueDate: { type: Date },
    Completed: { type: Boolean }
});

and we save a reference of the created context:

var TodoDatabase = $data.EntityContext.extend("TodoDatabase", {
    Todos: { type: $data.EntitySet, elementType: Todo }
});

then we can safely work these references:

var todoDB = new TodoDatabase("MyTodoDatase");
todoDB.onReady(function() {
    var tasks = todoDB.Todos.addMany([
        { Task: 'Step0: Get this this list', Completed: true },
        { Task: 'Step1: Define your data model'},
        { Task: 'Step2: Initialize data storage'}
    ]);
    todoDB.saveChanges(function() {
        tasks.forEach( function(todo) { alert(todo.Id) });
    });
});

if I don't save reference to the entity and the context I get this error

angular.js:12722 ReferenceError: Contact is not defined
    at Object.<anonymous> (app.js:343)
    at Object.invoke (angular.js:4535)
    at Object.enforcedReturnValue [as $get] (angular.js:4387)
    at Object.invoke (angular.js:4535)
    at angular.js:4352
    at getService (angular.js:4494)
    at Object.invoke (angular.js:4526)
    at extend.instance (angular.js:9380)
    at nodeLinkFn (angular.js:8497)
    at compositeLinkFn (angular.js:7929)
3
Ilia Yatchev On

It seems like both jaydata and onsenui are using window.Class, however their implementations differ significantly. Onsen uses John Resig's implementation while in jaydata's version Class is actually an instance of their ClassEngineBase. The problem of making these two implementations work together at least from my point of view is that in jaydata's version Class is actually an instance rather than a function. If it was a function it would've been easy to merge the two implementations by just adding the extend method to jaydata's implementation.

You could still try to do that, but it's not going to be as easy and some new bugs may occur if not done properly.

So your options are:

  1. Still try to merge the implementations
  2. Modify Onsen UI
  3. Modify Jaydata
  4. Wait for one of the two libs to fix the issue

1. Sequence: [jaydata, onsenui, patch], where patch is a modified version of the onsenui version.

(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
  this.Class.extend = function(prop) {
    var _super = this.prototype || {};
    initializing = true;
    var constructor = typeof this === 'function' ? this : function(){};
    var prototype = new constructor();
    initializing = false;

    for (var name in prop) {
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
            this._super = _super[name];
            var ret = fn.apply(this, arguments);
            this._super = tmp;
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    function Class() {
      if (!initializing && this.init)
        this.init.apply(this, arguments);
    }

    Class.prototype = prototype;
    Class.prototype.constructor = Class;
    Class.extend = arguments.callee;
    return Class;
  };
})();

However I haven't really tested it if it works, and there may be some issues.

  1. You aren't including angular-onsenui.js, so I guess you're using onsen 1, not onsen 2. Here's a slightly modified version of 1.3.15 which should not have collisions (not tested, sorry).

  2. In JayData they're storing the class in $data.Class so it turns out that there are only 2 places where the global one is used in http://include.jaydata.org/jaydata.js

    2874: $data.Class = Class = new ClassEngineBase();
    3342: global["$C"] = function () { Class.define.apply(Class, arguments); };
    

You could either remove the = Class from the first line and change both cases of the second line from Class to $data.Class, or just write var Class; on line 2873. - Actually it seems they already have implemented this change but it seems like it's not in the online version yet.

  1. So if you don't want to change the files I guess maybe JayData could have the updated version somewhere. For Onsen - the developement of Onsen 1 is already finished and we are working only on Onsen 2. The same bug will probably persist with the current beta, but it probably won't be too long before we fix it.