-
Notifications
You must be signed in to change notification settings - Fork 5
Persistence
TeamSnap.js provides a specialized feature called Persistence for working with single users such as in a browser-based application. When Persistence is enabled, it alters TeamSnap.js to automatically do a little more behind-the-scenes. Persistence keeps all loaded items in memory, links them together automatically by their links, ensures when items are loaded they update their existing versions rather than create duplicates, and provides a rollback/undo mechanism to revert to the last saved state.
The methods associated with Persistence are:
-
enablePersistence()
Enables persistence starting now, items previously loaded will not be persisted -
enablePersistence(cachedItems)
Starts persistence with objects loaded from cache (e.g.JSON.parse(JSON.stringify(teamsnap.getAllItems()))
) -
disablePersistence()
Disables, unlinks, and otherwise lets go of persisted items -
findItem(href)
Finds a loaded item byhref
when persistence is enabled -
getAllItems()
Returns all persisted items -
linkItems(items)
Adds provided items to Persistence and links them with existing and each other -
unlinkItems(items)
Removes provided items from Persistence and unlinks them -
unlinkTeam(team)
Removes a team and all of its data from Persistence
When enabling Persistence, items are given additional methods to help with this:
-
link(rel, relatedItem)
Sets the link (and foreignKeyId) of an item to another, and links them -
saveState()
Saves the state as it currently is, automatically called when loaded and after save -
rollback()
Rolls an item back to its last saved state
Persistence Linking will connect related items together. If you load a team, all its members, all its events, and all its availabilities, the items will all be linked together. You will be able to have arrays such as team.members
, member.availabilities
, event.availabilities
, and team.events
. You will be able to easily access related data such as member.team.name
and availability.member.firstName + ' - ' + availability.event.startDate
.
Note: it is easy for a member to link into its team and add itself to the team's members
array, but it is harder for the team to find all members that belong to it. Therefore, Linking works best when you load all the data at once or load the arrays of items after the single item (such as loading team before members, or events before availabilities). Persistence is really meant to work with a whole team's data (or more than one team) at a time.
A common problem that must be dealt with when keeping persistent data in-memory is when updating your data you can end up with duplicates. Persistence prevents this by ensuring only one item per href
is kept in memory. If you were to use teamsnap.createEvent({ href: 'http...12345' })
when an item by that href already existed, the existing item would be returned from the createEvent
method instead of a brand new one. If you call loadMembers(teamId)
once and get back 20 members, then call loadMembers(teamId)
again, you will get back those same 20 members, such that membersFirst[0] === membersSecond[0]
would be true. While Persistence ensures the items are not duplicated, items that are loaded later will update the data on existing items allowing a reload to refresh the data.
Another common problem with persistent data, especially in user-facing applications, is when a user changes the data of an item but then decides to cancel the operation, we need an easy way to revert to the original saved state. item.rollback()
does this automatically for us, including undoing any links we've created using item.link(rel, relatedItem)
since the last time the item was loaded or saved.
When using create*()
and item will be returned that hasn't been loaded or saved. In this case, you can use item.link(rel, relatedItem)
to temporarily link this un-saved item, but if the action is canceled and you call item.rollback()
, the item will be unlinked and removed.
Example:
var newMember = teamsnap.createMember();
newMember.link('team', team);
team.members.indexOf(newMember); // does not equal -1, the member exists in the array
newMember.rollback();
team.members.indexOf(newMember); // equals -1, the member is removed
In addition to the generic additions Persistence adds to TeamSnap.js when enabled, it also is smart about the needs of specific methods in TeamSnap.js. For example, when deleting a repeating event with include = 'future'
, Persistence will remove all the events deleted from memory, not just the one passed. When a member is created, Persistence loads all the availabilities
, customData
, and trackedItemStatuses
for that member automatically, and will remove all these objects when that member is deleted. Once you load a team, you can be assured that all the data for that team will be in-memory.
Because items are persistent in-memory, it is important that you remove items no longer needed. Persistence will automatically remove items that you delete, but it will not automatically remove items you are no longer using.
For example, if you have hundreds of teams, say you are a league commissioner, you may load a team into memory using bulkLoad(teamId)
so that you can access its data and do anything you need, however you should call teamsnap.unlinkTeam(team)
when done, otherwise you may end up with millions of items in-memory and crash your browser after loading many teams.