├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Alan deLevie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ParseAngularGuide 2 | ================= 3 | 4 | Collecting what I've learned building an Angular + Parse App 5 | 6 | ### Setup 7 | 8 | Include the Parse JS SDK. In this example, I'm just using Parse's CDN. 9 | 10 | `index.html`: 11 | 12 | ```html 13 | 14 | 15 | 16 | 17 | 18 | 19 | ``` 20 | 21 | Create an Angular Service to initialize the Parse JS SDK: 22 | 23 | ```javascript 24 | skeletonApp.service('ParseService', [function() { 25 | var app_id = "1234"; 26 | var js_key = "5678"; 27 | Parse.initialize(app_id, js_key); 28 | }]); 29 | ``` 30 | 31 | Now you have access to the JS SDK anywhere you inject `ParseService`. 32 | 33 | ### Queries 34 | 35 | Inside of the `success` callback, you must call `$scope.$apply` in order for the new data to be bound to the `$scope`. The same step is needed for `$rootScope`. 36 | 37 | ```javascript 38 | skeletonApp.controller('GameScoreListController', 39 | ['$scope', 'ParseService', function($scope, ParseService) { 40 | 41 | var GameScore = Parse.Object.extend("GameScore"); 42 | 43 | var query = new Parse.Query(GameScore); 44 | 45 | query.find({ 46 | success: function(results) { 47 | $scope.$apply(function() { 48 | $scope.gameScores = results; 49 | }); 50 | }, 51 | error: function(error) { 52 | console.log(error); 53 | } 54 | }); 55 | 56 | }]); 57 | ``` 58 | 59 | ### Inserting Data 60 | 61 | Just as with querying data, you'll need to add `$scope.$apply` inside of your `success` callback: 62 | 63 | ```javascript 64 | 'use strict'; 65 | 66 | skeletonApp.controller('GameScoreController', 67 | ['$scope', 'ParseService', function($scope, $location, ParseService) { 68 | 69 | $scope.submit = function() { 70 | 71 | var GameScore = Parse.Object.extend("GameScore"); 72 | 73 | var gameScore = new GameScore(); 74 | 75 | gameScore.set("score", 1337); 76 | gameScore.set("playerName", "Sean Plott"); 77 | gameScore.set("cheatMode", false); 78 | 79 | gameScore.save(null, { 80 | success: function(gameScoreAgain) { 81 | $scope.$apply(function() { 82 | $scope.gameScore = gameScoreAgain; 83 | }); 84 | }, 85 | error: function(gameScore, error) { 86 | alert('Failed to create new object, with error code: ' + error.description); 87 | } 88 | }); 89 | 90 | } 91 | 92 | 93 | }]); 94 | ``` 95 | 96 | ### Persisting logged in users with localStorage 97 | 98 | So far my favorite part of using the Parse JS SDK is that you don't need to touch `localStorage` to locally persist a user. 99 | 100 | ```javascript 101 | skeletonApp.controller('LoginController', 102 | ['$scope', 'ParseService', '$location', '$rootScope', function($scope, ParseService, $location, $rootScope) { 103 | 104 | // redirect to "/" if user is already logged in 105 | if ($rootScope.currentUser !== null) { 106 | $location.path("/"); 107 | } 108 | 109 | function loginSuccessful(user) { 110 | $rootScope.$apply(function() { 111 | // set the current user 112 | $rootScope.currentUser = Parse.User.current(); 113 | // redirect 114 | $location.path("/"); 115 | }); 116 | } 117 | 118 | function loginUnsuccessful(user, error) { 119 | alert("Error: " + error.message + " (" + error.code + ")"); 120 | } 121 | 122 | $rootScope.loggedIn = function() { 123 | if ($rootScope.currentUser === null) { 124 | return false; 125 | } else { 126 | return true; 127 | } 128 | }; 129 | 130 | $scope.login = function() { 131 | var username = $scope.login.username; 132 | var password = $scope.login.password; 133 | 134 | Parse.User.logIn(username, password, { 135 | success: loginSuccessful, 136 | error: loginUnsuccessful 137 | }); 138 | }; 139 | 140 | $scope.logout = funciton() { 141 | $rootScope.currentUser = null; 142 | Parse.User.logOut(); 143 | } 144 | 145 | }]); 146 | ``` 147 | 148 | In your views, you can hide and display different elements using the `ng-show` and `ng-hide` directives: 149 | 150 | ```html 151 |
152 | 153 |
154 | Welcome, {{ currentUser.get("username") }} (logout) 155 |
156 | 157 |
158 | Login or Create new account 159 |
160 | 161 |
162 | ``` --------------------------------------------------------------------------------