familysearch javascript sdk
DESCRIPTION
Slides from a talk given at RootsTech 2014 and also at the FamilySearch Developers Conference in September 2014TRANSCRIPT
FAMILYSEARCHJAVASCRIPT SDK
Dallan Quass
DISCLAIMERSNot official - not an official FamilySearch projectNot supported - code is provided as-isNot maintained - everything currently works...
WHY AN SDK?
6500 LINES OF CODE
6500 LINES OF CODE
WHAT DOES IT DO?REST API calls return JSON
==>
Javascript function calls return Javascript objects
FEATURESREST API calls can be made using single-line Javascript functions
Authentication is a single-line call
Access token can be saved in a cookie - notify on expiration
Sets headers, handles transient errors and throttling
Convenience functions to make it easy to process the response
Convenience functions return Javascript objects
Objects have single-line $save() and $delete() functions
You can extend object prototypes to include your own functions
DEPENDENCIESEither jQuery or AngularJS
No other dependencies
DIVERSIONPROMISES
ARE AWESOME!
MR. JAVA CALLS MISS REST ABOUT THEPARTY
Mr. Java: Miss REST, what time is the party?
Miss REST: I'll know in about an hour
Mr. Java: I'll hold
An hour goes by
Miss REST: The party is at 7pm
Mr. Java: Thanks!
Mr. Java plans for the party
MR. JAVASCRIPT TEXTS MISS REST ABOUTTHE PARTY
Mr. Javascript: Miss REST, would you text me back when you knowthe time of the party?
Miss REST: I promise I will
Mr. Javascript works on his family history
An hour goes by
Miss REST: The party is at 7pm
When Mr. Javascript is at a stopping spot in his family history, heplans for the party
THINK OF A PROMISE AS A SINGLE-USEEVENT BUS
var promise = REST.asyncFunction();
promise.then(function(response) { // do something with the response});
function asyncFunction() { var deferred = $.Deferred();
setTimeout(function() { deferred.resolve("Response"); }, 60*1000);
return deferred.promise();}
HANDLING REJECTIONvar promise = REST.asyncFunction();
promise.then(function(response) { // do something with the response}, function(errorResponse) { // handle the error});
function asyncFunction() { var deferred = $.Deferred();
setTimeout(function() { deferred.reject("Error"); }, 60*1000);
return deferred.promise();}
PROMISES CAN BE NESTEDMr. Javascript: Miss REST, would you text me back when you know
the time of the party?
Miss REST: I promise I will
Mr. Javascript works on his family history
Miss REST asks her friend Miss Party Planner to fulfill herpromise to Mr. Javascript
Miss REST: Miss Party Planner, would you text Mr. Javascript whenyou know the time of the party?
Miss Party Planner: I promise I will
An hour goes by
Miss Party Planner: Mr. Javascript, The party is at 7pm
When Mr. Javascript is at a stopping spot in his family history, heplans for the party
EXAMPLEvar promise = REST.asyncFunction();
promise.then(function(response) { // do something with the response});
function asyncFunction() { return $http('first URL').then(function(firstResponse) { var secondURL = fn(firstResponse); return $http(secondURL); });}
PROMISES CAN BE AGGREGATEDMr. Javascript: Miss REST, would you let me know when you find out
what Amy and Bill are wearing to the party?
Miss REST: I promise I will
Miss REST texts Amy and Bill asking them what they are wearing
Once Miss REST hears back from both Amy and Bill, she fulfillsher promise to Mr. Javascript
EXAMPLEvar promise = REST.asyncFunction();
promise.then(function(amyResponse, billResponse) { // do something with the responses});
function asyncFunction() { var amyPromise = amyAsyncFunction(); var billPromise = billAsyncFunction(); return $.when(amyPromise, billPromise);}
ENOUGH TALKLet's Code!
1. INITIALIZEFamilySearch.init({ app_key: 'WCQY-7J1Q-GKVV-7DNM-SQ5M-9Q5H-JX3H-CMJK', environment: 'sandbox', auth_callback: 'http://localhost:9000/#!/auth', http_function: $http, deferred_function: $q.defer, timeout_function: $timeout, save_access_token: true, auto_expire: true, auto_signin: true});
2. AUTHENTICATEFamilySearch.getAccessToken().then(function() { // user is authenticated - OAuth dance is complete});
3. MAKE API CALLSFamilySearch.getCurrentUserPersonId() .then(function(id) { FamilySearch.getAncestry(id) .then(function(response) { var persons = response.getPersons(); // do something with the Person objects }); });
FamilySearch.Person.prototype.isMale = function() { return this.display.gender === 'Male';};
ANOTHER EXAMPLEfunction createMemoryForPerson(file, person) { var fd = new FormData(); fd.append('artifact', file); // create memory return FamilySearch.createMemory(fd).then(function(memoryId) {
// read memory to get memory artifact URL (memory.about) return FamilySearch.getMemory(memoryId).then(function(response) { var memory = response.getMemory();
// create a memory persona from the person's name and the memory artifact URL var memoryPersona = new FamilySearch.MemoryPersona(person.$getDisplayName(), memory.about);
// add the memory persona to the memory return memory.$addMemoryPersona(memoryPersona).then(function(memoryPersonaRef) {
// add the memory persona reference to the person return person.$addMemoryPersonaRef(memoryPersonaRef).then(function() { // success! return memory; }); }); }); });};
PLUMBING & PORCELAIN
PLUMBINGFamilySearch.get('/platform/memories/memories/'+ urlencode(memoryId)) .then(function(response) { // process response });
USING THE SDKGithub repository
http://github.com/rootsdev/familysearch-javascript-sdk
Documentation
http://rootsdev.org/familysearch-javascript-sdk
Downloadable code
http://rootsdev.org/familysearch-javascript-sdk/familysearch-javascript-sdk.js
CONTRIBUTINGPULL REQUESTS ARE WELCOME!
COOL THINGS ABOUT THEBUILD WORKFLOW
jsHintKarmaTravis-CIGruntgrunt-ngdocs
ROOTSDEVRootsDev: loose organization of software engineers interested in
creating software for family history.
github organization: a low-volume google group with often-interesting discussions
github.com/rootsdev
Please join us!rootsdev.org
THE ENDSlides are at https://github.com/DallanQ/rootstech-2014-fs-js-
sdk-slides