sproutsocial / walltime-js

A JavaScript library for easily translating a UTC time to a "Wall Time" for a particular time zone.
MIT License
121 stars 12 forks source link

Example usage with Require.js #38

Closed justinwinslow closed 11 years ago

justinwinslow commented 11 years ago

I've not been able to find a good example of how to make this lib work with require.

If the config looks like this:

require.config({
  paths: {
    walltime: 'bower_components/walltime/client/walltime'
  }
})

and the module looks like this:

define(['walltime'], function(WallTime){
  var someUTCDate = new Date(new Date().getTime()),
        chicagoWallTime = WallTime.UTCToWallTime(someUTCDate, "America/Chicago");
})

I get Uncaught Error: Must call init with rules and zones before setting time zone

I assume this has something to do with walltime-data not being loaded. But, when I add that as a dependency in the config I get the same result (I think this is because the data attached itself to window.WallTime and the WallTime module itself never sees it).

Sooooo, what actually needs to happen for this to work?

jgable commented 11 years ago

I have a requirejs html test file I use to test with, maybe it's structure would help you out.

    <script type="text/javascript" src="../../client/walltime-data.js"></script>
    <script type="text/javascript" src="require.js"></script>
    <script>

        require.config({
            paths: {
                walltime: "../../client/walltime"
            },

            shim: {
                mocha: {
                    exports: 'mocha'
                }
            }
        });

        require(["chai", "mocha", "walltime"], function(chai, mocha, WallTime) {

            var should = chai.should();

            mocha.setup('bdd');

            describe("WallTime - RequireJS", function () {
                it("exists", function () {
                    should.exist(WallTime);
                    should.exist(WallTime.init);
                });
            });

            if (window.mochaPhantomJS) mochaPhantomJS.run()
            else mocha.run();
        });
    </script>

I'll load that up and see if it can execute the UTCToWallTime function. Would be good to add that to the tests anyway.

jgable commented 11 years ago

I'm getting the same error as you in my requirejs test. I was able to get it working with this:

<script type="text/javascript" src="require.js"></script>
<script>

    require.config({
        paths: {
            walltimedata: "../../client/walltime-data",
            walltime: "../../client/walltime"
        },

        shim: {
            mocha: {
                exports: 'mocha'
            },
            walltimedata: {
                exports: 'WallTime.data'
            }
        }
    });

    define("walltimelib", ["walltimedata", "walltime"], function (WallTimeData, WallTime) {
        WallTime.init(WallTimeData.rules, WallTimeData.zones);

        return WallTime;
    });

    require(["chai", "mocha", "walltimelib"], function (chai, mocha, WallTime) {

        var should = chai.should(),
            // Apollo 11 was the spaceflight that landed the first humans on the Moon, 
            // Americans Neil Armstrong and Buzz Aldrin, on July 20, 1969, at 20:18 UTC.
            landingTime = Date.UTC(1969, 6, 20, 20, 18, 0, 0);

        mocha.setup('bdd');

        describe("WallTime - RequireJS", function () {
            it("exists", function () {
                should.exist(WallTime);
                should.exist(WallTime.init);
            });

            it("can convert Apollo 11 landing time for America/Chicago", function () {
                var chicagoLandingTime = WallTime.UTCToWallTime(landingTime, "America/Chicago");

                should.exist(chicagoLandingTime);

                chicagoLandingTime.getFullYear().should.equal(1969);
                chicagoLandingTime.getMonth().should.equal(6);
                chicagoLandingTime.getDate().should.equal(20);
                chicagoLandingTime.getHours().should.equal(14);
                chicagoLandingTime.getMinutes().should.equal(18);
            });
        });

        if (window.mochaPhantomJS) mochaPhantomJS.run()
        else mocha.run();
    });
</script>

I think I could make this happen as part of the define() call in walltime, I'll see what I can do to make it easier.

justinwinslow commented 11 years ago

Thanks for your quick response. I'll mess around with this but yeah, it would be pretty sweet if the WallTime was able to import the data automagically.

jgable commented 11 years ago

Ok, with the latest version of walltime the data files all will detect if requirejs is loaded and use the define method to define themselves as walltime-data. Now you should be able to do something like this:

Here is an example of using with requireJS:

<script type="text/javascript" src="require.js"></script>
<script type="text/javascript" src="bower_components/walltime/client/walltime-data.js"></script>
<script type="text/javascript">
require.config({
  paths: {
    walltime: 'bower_components/walltime/client/walltime'
  }
});

define(['walltime'], function(WallTime){
  var someUTCDate = new Date(),
        chicagoWallTime = WallTime.UTCToWallTime(someUTCDate, "America/Chicago");
});
</script>

I'll try to update the readme with this info as well.

jgable commented 11 years ago

BTW, I've created an actual bower package for the repo now, it's registered as walltime-js. If you could test it out and give some feedback that would be great.

justinwinslow commented 11 years ago

Sounds great! I'll give it a look tomorrow. Thanks again for the fast turn around.

justinwinslow commented 11 years ago

If I just list 'walltime' in the paths hash I get: To use WallTime with requirejs please include the walltime-data.js script before requiring walltime. If I add the data file mapped to 'walltime-data' I get the same message.

If I add a shim it works:

shim: {
  walltime: {
    deps: ['walltime-data']
  }
}

Did you observe different behavior?

justinwinslow commented 11 years ago

Also, the latest release works great with Bower. Only thing is it seems you might have tagged with '0.1.1' as the version in bower.json? It's fine in master, Bower just raised a mismatched version flag.

jgable commented 11 years ago

You have to actually load the walltime-data file before walltime in order for it to automatically initialize. Notice the way I put the walltime-data.js script in below the require.js script tag?

<script type="text/javascript" src="require.js"></script>
<script type="text/javascript" src="bower_components/walltime/client/walltime-data.js"></script>
<script type="text/javascript">
require.config({
  /* ... */
})
</script>

You could also try to just require(...) the walltime-data file but that could be a little messy. This is the cleanest way I can come up with to have everything auto initialize.

jgable commented 11 years ago

Fixed the tagging mismatch with bower as well. Thanks for the feedback on that.

justinwinslow commented 11 years ago

Gotcha, the shim works, I think I'll rock that for now.