diff --git a/History.md b/History.md index d016c40ffb..a89be7e134 100644 --- a/History.md +++ b/History.md @@ -43,6 +43,9 @@ * Reduced unecessary MongoDB re-polling of live queries. +* Added `Session.setDefault(key, value)` so you can easily provide initial + values for session variables that will not be clobbered on hot code push. + * Improved UI for running tinytest package tests in-browser. * Upgraded UglifyJS2 to version 2.2.5 diff --git a/docs/client/api.html b/docs/client/api.html index 728448d5ae..2066769ca8 100644 --- a/docs/client/api.html +++ b/docs/client/api.html @@ -1163,6 +1163,11 @@ Example: See [`Meteor.deps`](#meteor_deps) for another example. +{{> api_box setDefault}} + +This is useful in initialization code, to avoid re-initializing a session +variable every time a new version of your app is loaded. + {{> api_box get}} Example: diff --git a/docs/client/api.js b/docs/client/api.js index c442898588..54d55735cf 100644 --- a/docs/client/api.js +++ b/docs/client/api.js @@ -1367,6 +1367,21 @@ Template.api.set = { ] }; +Template.api.setDefault = { + id: "session_set_default", + name: "Session.setDefault(key, value)", + locus: "Client", + descr: ["Set a variable in the session if it is undefined. Otherwise works exactly the same as [`Session.set`](#session_set)."], + args: [ + {name: "key", + type: "String", + descr: "The key to set, eg, `selectedItem`"}, + {name: "value", + type: "EJSON-able object or undefined", + descr: "The new value for `key`"} + ] +}; + Template.api.get = { id: "session_get", name: "Session.get(key)", diff --git a/docs/client/docs.js b/docs/client/docs.js index 613886a013..749ac59b82 100644 --- a/docs/client/docs.js +++ b/docs/client/docs.js @@ -161,6 +161,7 @@ var toc = [ "Session", [ "Session.set", + {name: "Session.setDefault", id: "session_set_default"}, "Session.get", "Session.equals" ], diff --git a/examples/todos/client/todos.js b/examples/todos/client/todos.js index c9b8a1e0b7..dfb38295a5 100644 --- a/examples/todos/client/todos.js +++ b/examples/todos/client/todos.js @@ -5,19 +5,19 @@ Lists = new Meteor.Collection("lists"); Todos = new Meteor.Collection("todos"); // ID of currently selected list -Session.set('list_id', null); +Session.setDefault('list_id', null); // Name of currently selected tag for filtering -Session.set('tag_filter', null); +Session.setDefault('tag_filter', null); // When adding tag to a todo, ID of the todo -Session.set('editing_addtag', null); +Session.setDefault('editing_addtag', null); // When editing a list name, ID of the list -Session.set('editing_listname', null); +Session.setDefault('editing_listname', null); // When editing todo text, ID of the todo -Session.set('editing_itemname', null); +Session.setDefault('editing_itemname', null); // Subscribe to 'lists' collection on startup. // Select a list once data has arrived. @@ -66,6 +66,7 @@ var okCancelEvents = function (selector, callbacks) { cancel.call(this, evt); } }; + return events; }; @@ -304,8 +305,11 @@ var TodosRouter = Backbone.Router.extend({ ":list_id": "main" }, main: function (list_id) { - Session.set("list_id", list_id); - Session.set("tag_filter", null); + var oldList = Session.get("list_id"); + if (oldList !== list_id) { + Session.set("list_id", list_id); + Session.set("tag_filter", null); + } }, setList: function (list_id) { this.navigate(list_id, true); diff --git a/packages/session/session.js b/packages/session/session.js index a8aade94d3..226668cec0 100644 --- a/packages/session/session.js +++ b/packages/session/session.js @@ -40,6 +40,16 @@ } }, + setDefault: function (key, value) { + var self = this; + // for now, explicitly check for undefined, since there is no + // Session.clear(). Later we might have a Session.clear(), in which case + // we should check if it has the key. + if (self.keys[key] === undefined) { + self.set(key, value); + } + }, + get: function (key) { var self = this; self._ensureKey(key); diff --git a/packages/session/session_tests.js b/packages/session/session_tests.js index 2cee082469..97b00d9762 100644 --- a/packages/session/session_tests.js +++ b/packages/session/session_tests.js @@ -1,5 +1,21 @@ (function () { + Tinytest.add('session - setDefault', function (test) { + Session.setDefault('def', "argyle"); + test.equal(Session.get('def'), "argyle"); + Session.set('def', "noodle"); + test.equal(Session.get('def'), "noodle"); + Session.set('nondef', "potato"); + test.equal(Session.get('nondef'), "potato"); + Session.setDefault('nondef', "eggs"); + test.equal(Session.get('nondef'), "potato"); + // This is so the test passes the next time, after hot code push. I know it + // doesn't return it to the completely untouched state, but we don't have + // Session.clear() yet. When we do, this should be that. + delete Session.keys['def']; + delete Session.keys['nondef']; + }); + Tinytest.add('session - get/set/equals types', function (test) { test.equal(Session.get('u'), undefined); test.isTrue(Session.equals('u', undefined));