How to initialize facebook sdk and parse for parse.com facebook login in angularjs $app.run and factory/service. Functions in the controller can then be used by making sure that both libs have been loaded and initialized. Solution to the following errors ``` You need to call Parse.initialize before using Parse. The Facebook JavaScript SDK must be loaded before calling init. ``` #### constants.js ``` angular.module('constants', [ ]) .constant('ENVIRONMENT', 'development') .constant('FACEBOOK_SMM_APP_ID', '123456789') .constant('FACEBOOK_SMM_SCOPES', 'email, user_friends, user_photos,user_birthday,user_work_history,user_education_history,user_about_me,user_interests,user_hometown,user_likes') .constant('PARSE_SMM_APP_ID', 'abcdefghijklmnop') .constant('PARSE_SMM_JAVASCRIPT_KEY', 'abcdefghijklmnop') ``` #### app.js ``` angular.module('starterApp', ['ngRoute', 'constants', 'me']) .config(function($routeProvider) { // whatever your routes }) .run(['$rootScope', '$location', function ($rootScope,$location, FACEBOOK_SMM_APP_ID, PARSE_SMM_APP_ID, PARSE_SMM_JAVASCRIPT_KEY) { // material works with arrive js $.material.init(); window.fbAsyncInit = function() { window.fbApiInit = true; $rootScope.fbApiInit = true; }; (function(d, s, id){ var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) {return;} js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); $rootScope.$on('$routeChangeStart', function (event) { console.log("App Run") // if (!Auth.isLoggedIn()) { // console.log('DENY'); // event.preventDefault(); // $location.path('/login'); // } // else { // console.log('ALLOW'); // $location.path('/home'); // } // }) angular.element(document).ready(function () { $("body").tooltip({ selector: '[data-toggle=tooltip]' }); }); }]) .service('appInitFactory', function($q, $rootScope, FACEBOOK_SMM_APP_ID, PARSE_SMM_APP_ID, PARSE_SMM_JAVASCRIPT_KEY) { function fbEnsureInit(callback) { if( ! $rootScope.fbApiInit ) { setTimeout(function() {fbEnsureInit(callback);}, 50); } else { callback(); } } function parseEnsureInit(callback) { Parse.initialize(PARSE_SMM_APP_ID, PARSE_SMM_JAVASCRIPT_KEY); if (! Parse.applicationId ) { setTimeout(function() {parseEnsureInit(callback);}, 50); } else { callback(); } } function fbAndParseEnsureInit (callback) { parseEnsureInit(function(){ if (!$rootScope.fbApiInit) { setTimeout(function() {fbAndParseEnsureInit(callback);}, 50); } else { Parse.FacebookUtils.init({ // this line replaces FB.init({ appId: FACEBOOK_SMM_APP_ID, // Facebook App ID status: true, // check Facebook Login status cookie: true, // enable cookies to allow Parse to access the session xfbml: true, // initialize Facebook social plugins on the page version: 'v2.2' // point to the latest Facebook Graph API version }); callback(); } }) } // Promise-based API return { facebookInitialize: function(callback) { var deferred = $q.defer(); fbEnsureInit(function(){ deferred.resolve(true); }) return deferred.promise; }, parseInitialize: function(callback) { var deferred = $q.defer(); parseEnsureInit(function(){ deferred.resolve(true); }) return deferred.promise; }, fbAndParseInitialize: function(callback) { var deferred = $q.defer(); fbAndParseEnsureInit(function(){ deferred.resolve(true); }) return deferred.promise; } }; }) ``` #### me.js ``` angular.module('me', ['starterApp.directives']) .controller('MeController', function(appInitFactory, $scope, $routeParams,$log, ENVIRONMENT, FACEBOOK_SMM_APP_ID, PARSE_SMM_APP_ID, PARSE_SMM_JAVASCRIPT_KEY) { appInitFactory .facebookInitialize() .then(function(ret) { console.log("this will be run once just FB is initialized"); }) appInitFactory .fbAndParseInitialize() .then(function(ret) { console.log("this will be run once FB & Parse are initialized"); FB.api('/me', function(response) { console.log(response); }); }) }) ```