Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing instantiated objects in requirejs

I'm defining a module Foo and I am instantiating it within another module Bar. I have a third module Other which I'd like to provide with the same instance of Foo that Bar created and modified.

define('Foo', [], function() {
    var test = function() {
        this.foo = 'foo';        
    };

    return test;
});

define('Bar', ['Foo'], function(Foo) {
    Foo = new Foo();
    Foo.bar = 'bar';
    console.log('From bar', Foo);
});

define('Other', ['Foo'], function(Foo) {
    console.log('From the other', Foo);
});


require(['Foo', 'Bar', 'Other'], function(Foo, Bar, Other) {
    console.log('Bringing it all together');
});

http://jsfiddle.net/radu/Zhyx9/

Without require, I would be doing something like:

App = {};

App.Foo = function() {
    this.foo = 'foo';
}

App.Bar = function() {
    App.Foo = new App.Foo();
    App.Foo.bar = 'bar';
    console.log('From bar', App.Foo);
}

App.Other = function() {
   console.log('From other', App.Foo);
}

App.Bar();
App.Other();

http://jsfiddle.net/radu/eqxaA/

I know I must be missing something here and since this is one my first forays in requirejs there is probably some sort of misunderstanding mixed in. The example may look contrived but I'm coming across something similar in shoehorning a project into using Backbone and RequireJS. ​

like image 957
Radu Avatar asked Sep 11 '12 02:09

Radu


3 Answers

What you expose from the module using return is accessible from the argument that represents that module in the requiring module

Here's your demo, modified

define('Bar', ['Foo'], function(Foo) {
    Foo = new Foo();
    Foo.bar = 'bar';

    //return instantiated Foo
    return Foo;
});


require(['Foo', 'Bar', 'Other'], function(Foo, Bar, Other) {
    //Bar is the instantiated Foo, exposed from Bar
    console.log(Bar);
});
like image 58
Joseph Avatar answered Nov 16 '22 08:11

Joseph


I posted this as comment to one of the answers but I was aware that I could share an instance like so:

define('Foo', [], function() {
    var test = function() {
        this.foo = 'foo';        
    };

    return new test();
});

define('Bar', ['Foo'], function(Foo) {
    Foo.bar = 'bar';
    console.log('From bar', Foo);
});

define('Other', ['Foo'], function(Foo) {
    Foo.other = 'other';
    console.log('From the other', Foo);
});


require(['Foo', 'Bar', 'Other'], function(Foo, Bar, Other) {
    console.log('Bringing it all together');
});

http://jsfiddle.net/radu/XEL6S/

However, the reason I didn't do this in the first place was that the Foo module couldn't instantiate itself as it required the DOM to be ready. However, being new to RequireJS, I wasn't aware that this sort of functionality is built in. In other words, to share an instance of a module Foo as I specified above, instantiate in its definition and add the domReady module as specified in the requireJS docs.

like image 39
Radu Avatar answered Nov 16 '22 08:11

Radu


The return value from the module is what requirejs considers the exposed api. So your console.log statements are disrupting that.

You need to return something from the function like so:

define('Bar', ['Foo'], function(Foo) {
    var Bar = { my: 'bar'};
    //or maybe return a function or whatever 
    return Bar;
 });
like image 1
SonOfNun Avatar answered Nov 16 '22 08:11

SonOfNun