├── .gitignore ├── DefinitelyTyped └── AngularService.d.ts ├── LICENSE ├── README.md ├── bower.json ├── dist ├── angular-azure-mobile-service.js └── angular-azure-mobile-service.min.js ├── gulpfile.js ├── package.json └── src └── angular-azure-mobile-service.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | node_modules 3 | .directory 4 | demo 5 | -------------------------------------------------------------------------------- /DefinitelyTyped/AngularService.d.ts: -------------------------------------------------------------------------------- 1 |  2 | 3 | interface IAzureService { 4 | query(tableName: string, parameters?: IAzureParameters, withFilterFn?: Function): ng.IPromise; 5 | insert(tableName: string, obj: T, withFilterFn?: Function): ng.IPromise; 6 | update(tableName: string, obj: T, withFilterFn?: Function): ng.IPromise; 7 | del(tableName: string, obj: T, withFilterFn?: Function): ng.IPromise; 8 | getAll(tableName: string, withFilterFn?: Function): ng.IPromise; 9 | getById(tableName: string, id: string, withFilterFn?: Function): ng.IPromise; 10 | read(tableName: string, parameters?: IAzureParameters, withFilterFn?:Function): ng.IPromise; 11 | login(oauthProvider: string, token: Object): ng.IPromise; 12 | setCurrentUser(userObj: Object): void; 13 | getCurrentUser(): Object; 14 | logout(): void; 15 | isLoggedIn(): boolean; 16 | invokeApi(name: string, params: IAzureApiParameters): ng.IPromise; 17 | } 18 | 19 | interface IAzureParameters { 20 | criteria?: Object; 21 | params?: Array; 22 | columns?: Array; 23 | take?: number; 24 | skip?: number; 25 | orderBy?: Array; 26 | column?: string; 27 | direction?: string; 28 | } 29 | 30 | interface IAzureApiParameters { 31 | method: string; 32 | body?: Object; 33 | parameters?: Object; 34 | headers?: Object; 35 | } 36 | 37 | interface IAzureParamOrderBy { 38 | column: string; 39 | direction: string; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Terry Moore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | angular-azure-mobile-service 2 | ============================ 3 | 4 | An AngularJS service for the Azure Mobile Service Client. 5 | 6 | This supports simple and complex queries, inserts, updates, and deletes. Supports login and logout of Azure authentication identities such as Google, Twitter, Facebook, Windows Live, and Azure Active Directory. Also supports invoking your custom azure api calls. 7 | 8 | Installation 9 | ------------- 10 | ``` 11 | bower install angular-azure-mobile-service 12 | ``` 13 | ``` 14 | npm install angular-azure-mobile-service 15 | ``` 16 | 17 | CDN 18 | ------ 19 | ```HTML 20 | 21 | ``` 22 | Check for latest published CDN version [here] (https://cdnjs.com/libraries/angular-azure-mobile-service) 23 | 24 | 25 | Required dependancies 26 | ----------------------- 27 | * [AngularJS] (http://www.angularjs.org) 28 | * [Azure Mobile Service Client] (https://azure.microsoft.com/en-us/documentation/services/mobile-services/) 29 | 30 | 31 | Add the Azure Mobile Service Client to your index.html file 32 | ```HTML 33 | 34 | ``` 35 | 36 | After downloading the `angular-azure-mobile-service.js` to your AngularJS project then 37 | 38 | Add `'azure-mobile-service.module'` to your main angular.module like so 39 | ```javascript 40 | angular.module('myapp', ['myApp.controllers', 'myApp.services', 'azure-mobile-service.module']); 41 | ```` 42 | 43 | API Key information **New in 1.1** 44 | ------------------- 45 | Create an AngularJS `constant` service called `AzureMobileServiceClient`, this will provide the Azure Mobile service with the API Key and URL and will not get overwritten with bower updates. 46 | 47 | If you want to store the current user in localStorage instead of sessionStorage then add `STORAGE: 'local'` to the AzureMobileServiceClient settings object. 48 | 49 | ```javascript 50 | angular.module('your-module-name').constant('AzureMobileServiceClient', { 51 | API_URL : 'https://.azure-mobile.net/', 52 | API_KEY : '', 53 | }); 54 | 55 | ``` 56 | 57 | 58 | How to use 59 | ------------- 60 | Add the Azureservice as a dependacy to your controller like so: 61 | ```javascript 62 | angular.module('myapp') 63 | .controller('MainCtrl', function ($scope, Azureservice) { 64 | ... 65 | }) 66 | ``` 67 | 68 | This will expose the following methods 69 | 70 | * [Azureservice.query(tableName, parameters, withFilterFn)] (#azureservicequerytablename-parameters-withfilterfn) 71 | * [Azureservice.insert(tableName, obj, withFilterFn)] (#azureserviceinserttablename-obj-withfilterfn) 72 | * [Azureservice.update(tableName, obj, withFilterFn)] (#azureserviceupdatetablename-obj-withfilterfn) 73 | * [Azureservice.del(tableName, obj, withFilterFn)] (#azureservicedeltablename-obj-withfilterfn) 74 | * [Azureservice.getAll(tableName, withFilterFn)] (#azureservicegetalltablename-withfilterfn) 75 | * [Azureservice.getById(tableName, id, withFilterFn)] (#azureservicegetbyidtablename-id-withfilterfn) 76 | * [Azureservice.read(tableName, parameters, withFilterFn)] (#azureservicereadtablename-parameters-withfilterfn) 77 | * [Azureservice.login(oauthProvider, token)] (#azureserviceloginoauthprovider) 78 | * [Azureservice.logout()] (#azureservicelogout) 79 | * [Azureservice.setCurrentUser(userObj)] (#azureservicesetcurrentuseruserobj) 80 | * [Azureservice.getCurrentUser()] (#azureservicegetcurrentuser) 81 | * [Azureservice.isLoggedIn()] (#azureserviceisloggedin) 82 | * [Azureservice.invokeApi()] (#azureserviceinvokeapiname-params) 83 | 84 | 85 | 86 | Azureservice.query(tableName, parameters, withFilterFn) 87 | ================= 88 | Query the Azure database 89 | 90 | Parameters: 91 | --------------- 92 | **tableName** Required 93 | 94 | ```` 95 | The Azure table to query 96 | ``` 97 | 98 | **parameters** Optional, Javascript object used filter the query 99 | 100 | ``` 101 | { 102 | criteria //A javascript object or a function to filter 103 | //If function then it must be an OData predicate. 104 | params //Array of parameters to pass the criteria function 105 | columns //Array of column names to return 106 | take //Number of results to return 107 | skip //Number of reuslts to skip over 108 | columns //Array of column names to return 109 | orderBy //Array of objects 110 | column //Column name to sort by 111 | direction //Direction to sort : asc || desc 112 | systemProperties //Number for system property to get 113 | //__createdAt: 1 114 | //__updatedAt: 2 115 | //__version: 4 116 | //All: 65535 117 | //None: 0 118 | } 119 | ``` 120 | 121 | [More information] (http://www.windowsazure.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#querying) about what each parameter does 122 | 123 | 124 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 125 | 126 | ```` 127 | A function that can read and write arbitrary properties or add additional headers to the request 128 | ``` 129 | 130 | Returns 131 | ----------- 132 | AngularJS Promise 133 | 134 | Example: 135 | --------- 136 | Simple query to return all results from the todoListTable 137 | Note: The empty object is optional. 138 | 139 | ```javascript 140 | Azureservice.query('todoListTable', {}) 141 | .then(function(items) { 142 | // Assigin the results to a $scope variable 143 | $scope.items = items; 144 | 145 | }, function(err) { 146 | console.error('There was an error quering Azure ' + err); 147 | }); 148 | 149 | ``` 150 | 151 | Query to return all items in the todoList table with a column isFinished value of false 152 | ```javascript 153 | 154 | Azureservice.query('todoListTable', { 155 | criteria: { 156 | isFinished:false 157 | } 158 | }) 159 | .then(function(items) { 160 | // Assigin the results to a $scope variable 161 | $scope.items = items; 162 | 163 | }, function(err) { 164 | console.error('There was an error quering Azure ' + err); 165 | }); 166 | 167 | ``` 168 | 169 | Same query as before but this time ordering the results name ascending and owner descending 170 | ```javascript 171 | Azureservice.query('todoListTable', { 172 | criteria: { 173 | isFinished:false 174 | }, 175 | orderBy: [ 176 | { 177 | column:'name', 178 | direction:'asc' 179 | }, 180 | { 181 | column:'owner', 182 | direction:'desc' 183 | } 184 | ] 185 | }) 186 | .then(function(items) { 187 | // Assigin the results to a $scope variable 188 | $scope.items = items; 189 | 190 | }, function(err) { 191 | console.error('There was an error quering Azure ' + err); 192 | }); 193 | 194 | ``` 195 | 196 | Same query as before but adding the pagination options of skip and take (See Azure docs) and returning just the colums name, isFinished 197 | 198 | ```javascript 199 | Azureservice.query('todoListTable', { 200 | criteria: { 201 | isFinished:false 202 | }, 203 | orderBy: [ 204 | { 205 | column:'name', 206 | direction:'asc' 207 | }, 208 | { 209 | column:'owner', 210 | direction:'desc' 211 | } 212 | ], 213 | skip: 10, 214 | take: 25, 215 | columns: ['name', 'isFinished'] 216 | }) 217 | .then(function(items) { 218 | // Assigin the results to a $scope variable 219 | $scope.items = items; 220 | 221 | }, function(err) { 222 | console.error('There was an error quering Azure ' + err); 223 | }); 224 | 225 | ``` 226 | 227 | For complex queries you can pass a pedicate function into the critera instead of an object, if you need to pass varibles to the function then pass add the params array. 228 | You can still pass all the take, columns, skip parameters also but not shown here for reduce complexity 229 | 230 | This will run the criteria function against the results passing in params array. This will return all rows that have a column name with terry in it. Simalar to a SQL LIKE 231 | 232 | ```javascript 233 | Azureservice.query('todoListTable', { 234 | criteria: function(param) { 235 | return this.name.indexOf(param[0]) !== -1; // The this keyword is in referece to the Azure results 236 | }, 237 | params: ['terry'] 238 | }) 239 | .then(function(items) { 240 | // Assigin the results to a $scope variable 241 | $scope.items = items; 242 | 243 | }, function(err) { 244 | console.error('There was an error quering Azure ' + err); 245 | }); 246 | 247 | ``` 248 | 249 | 250 | Azureservice.insert(tableName, obj, withFilterFn) 251 | ================= 252 | Insert data into the Azure database 253 | 254 | Parameters: 255 | --------------- 256 | **tableName** Required 257 | 258 | ```` 259 | The Azure table to insert to 260 | ``` 261 | 262 | **obj** Required 263 | 264 | ``` 265 | Javascript object containing the columns and values to insert in to the database 266 | ``` 267 | 268 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 269 | 270 | ```` 271 | A function that can read and write arbitrary properties or add additional headers to the request 272 | ``` 273 | 274 | Returns 275 | ----------- 276 | AngularJS Promise 277 | 278 | 279 | Example 280 | ------------- 281 | ```javascript 282 | Azureservice.insert('todoListTable', { 283 | name: 'This is the task', 284 | owner: 'Terry Moore', 285 | isFinished: false 286 | }) 287 | .then(function() { 288 | console.log('Insert successful'); 289 | }, function(err) { 290 | console.error('Azure Error: ' + err); 291 | }); 292 | 293 | ``` 294 | 295 | 296 | Azureservice.update(tableName, obj, withFilterFn) 297 | ================= 298 | Query the Azure database 299 | 300 | Parameters: 301 | --------------- 302 | **tableName** Required 303 | 304 | ```` 305 | The Azure table to update 306 | ``` 307 | 308 | **obj** Required 309 | 310 | ``` 311 | Javascript object containing the columns and values to udpate in to the database. Must contain Azure ID column 312 | ``` 313 | 314 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 315 | 316 | ```` 317 | A function that can read and write arbitrary properties or add additional headers to the request 318 | ``` 319 | 320 | Returns 321 | ----------- 322 | AngularJS Promise 323 | 324 | Example 325 | ------------- 326 | ```javascript 327 | Azureservice.update('todoListTable', { 328 | id: '5A25CD78-F2D9-413C-81CA-6EC090590AAF', 329 | isFinished: true 330 | }) 331 | .then(function() { 332 | console.log('Update successful'); 333 | }, function(err) { 334 | console.error('Azure Error: ' + err); 335 | }); 336 | 337 | ``` 338 | 339 | Returns 340 | ----------- 341 | AngularJS Promise 342 | 343 | 344 | Azureservice.del(tableName, obj, withFilterFn) 345 | ================= 346 | Delete from the Azure database 347 | 348 | Parameters: 349 | --------------- 350 | **tableName** Required 351 | 352 | ```` 353 | The Azure table to delete from 354 | ``` 355 | 356 | **obj** Required 357 | 358 | ``` 359 | Javascript object containing the criteria for rows from the database. 360 | ``` 361 | 362 | 363 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 364 | 365 | ```` 366 | A function that can read and write arbitrary properties or add additional headers to the request 367 | ``` 368 | 369 | Returns 370 | ----------- 371 | AngularJS Promise 372 | 373 | Example 374 | ------------- 375 | ```javascript 376 | Azureservice.del('todoListTable', { 377 | id: '5A25CD78-F2D9-413C-81CA-6EC090590AAF' 378 | }) 379 | .then(function() { 380 | console.log('Delete successful'); 381 | }, function(err) { 382 | console.error('Azure Error: ' + err); 383 | }); 384 | 385 | ``` 386 | 387 | Azureservice.getAll(tableName, withFilterFn) 388 | ================= 389 | Query all data from table. 390 | Alias to Azureservice.query(tableName, {}) 391 | 392 | Parameters: 393 | --------------- 394 | **tableName** Required 395 | 396 | ```` 397 | The Azure table to get all data from 398 | ``` 399 | 400 | 401 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 402 | 403 | ```` 404 | A function that can read and write arbitrary properties or add additional headers to the request 405 | ``` 406 | 407 | Returns 408 | ----------- 409 | AngularJS Promise 410 | 411 | Example 412 | ------------- 413 | ```javascript 414 | Azureservice.getAll('todoListTable') 415 | .then(function(items) { 416 | console.log('Query successful'); 417 | $scope.item = items; 418 | }, function(err) { 419 | console.error('Azure Error: ' + err); 420 | }); 421 | 422 | ``` 423 | 424 | Azureservice.getById(tableName, id, withFilterFn) 425 | ================= 426 | Get item from database by id 427 | 428 | Parameters: 429 | --------------- 430 | **tableName** Required 431 | 432 | ```` 433 | The Azure table to query from 434 | ``` 435 | 436 | **id** Required 437 | 438 | ``` 439 | The row id 440 | ``` 441 | 442 | 443 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 444 | 445 | ```` 446 | A function that can read and write arbitrary properties or add additional headers to the request 447 | ``` 448 | 449 | Returns 450 | ----------- 451 | AngularJS Promise 452 | 453 | Example 454 | ------------- 455 | ```javascript 456 | Azureservice.getById('todoListTable', '5A25CD78-F2D9-413C-81CA-6EC090590AAF') 457 | .then(function(item) { 458 | console.log('Query successful'); 459 | $scope.item = item; 460 | }, function(err) { 461 | console.error('Azure Error: ' + err); 462 | }); 463 | 464 | ``` 465 | 466 | Azureservice.read(tableName, parameters, withFilterFn) 467 | ================= 468 | Execute read-query in Azure with optional parameters in the URI that can be read by the Azure JS backend (request.parameters.property). 469 | 470 | Parameters: 471 | --------------- 472 | **tableName** Required 473 | 474 | ```` 475 | The Azure table to get all data from 476 | ``` 477 | 478 | **parameters** Optional 479 | ```` 480 | An object of user-defined parameters and values to include in the request URI query string 481 | Or as a string to pass an oData query filter. 482 | ```` 483 | 484 | **withFilterFn** Optional [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#customizing) 485 | 486 | ```` 487 | A function that can read and write arbitrary properties or add additional headers to the request 488 | ``` 489 | 490 | Returns 491 | ----------- 492 | AngularJS Promise 493 | 494 | Example with parameters object 495 | ------------- 496 | ```javascript 497 | Azureservice.read('todoListTable',{ 498 | apiVersion: "1.0", 499 | isCompleted: true 500 | }) 501 | .then(function(items) { 502 | console.log('Query successful'); 503 | $scope.item = items; 504 | }, function(err) { 505 | console.error('Azure Error: ' + err); 506 | }); 507 | 508 | ``` 509 | 510 | Example with parameters as an oData filter string 511 | ------------- 512 | ```javascript 513 | Azureservice.read('todoListTable', "$filter=name eq 'Test User'") 514 | .then(function(items) { 515 | console.log(items) 516 | }).catch(function(error) { 517 | console.log(error) 518 | }) 519 | 520 | ``` 521 | 522 | 523 | 524 | 525 | Azureservice.login(oauthProvider, token) 526 | ================= 527 | Login using the specified OAuth Provider and optinally provide an existing authentication token. 528 | Users logins are currently session based. This may change in the future. 529 | [More information] (http://www.windowsazure.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/#caching) 530 | 531 | 532 | Parameters: 533 | --------------- 534 | **oauthProvider** Required 535 | 536 | ```` 537 | The OAuth provider 538 | Vaild options are 'google', 'twitter', 'facebook', 'microsoftaccount', 'aad' 539 | ``` 540 | 541 | **token** Optional 542 | 543 | ```` 544 | Optional authentication token used to login to the provider 545 | ``` 546 | 547 | Returns 548 | ----------- 549 | AngularJS Promise 550 | 551 | 552 | Example 553 | ------------- 554 | ```javascript 555 | // New login to provider 556 | Azureservice.login('google') 557 | .then(function() { 558 | console.log('Login successful'); 559 | }, function(err) { 560 | console.error('Azure Error: ' + err); 561 | }); 562 | 563 | // Use existing token to login 564 | Azureservice.login('google', { id_token: 'qwerty12345...' }) 565 | .then(function() { 566 | console.log('Login successful'); 567 | }, function(err) { 568 | console.error('Azure Error: ' + err); 569 | }); 570 | ``` 571 | 572 | 573 | 574 | 575 | Azureservice.setCurrentUser(userObj) 576 | ================= 577 | Use this method to set the current user for the MS Client when using custom authentication. 578 | [More information] (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-get-started-custom-authentication/) 579 | 580 | 581 | Parameters: 582 | --------------- 583 | **userObj** Required 584 | 585 | ```` 586 | The user object that is returned from your custom authentication. 587 | ``` 588 | 589 | Returns 590 | ----------- 591 | 592 | 593 | 594 | Example 595 | ------------- 596 | ```javascript 597 | Azureservice.setCurrentUser(userObj); 598 | ``` 599 | 600 | 601 | 602 | Azureservice.getCurrentUser() 603 | ================= 604 | Use this method to get the current user object from the MS Client. 605 | 606 | 607 | Parameters: 608 | --------------- 609 | 610 | None 611 | 612 | Returns 613 | ----------- 614 | 615 | The user object that is logged in with Azure authentication, or null if none is logged in. 616 | 617 | 618 | 619 | Example 620 | ------------- 621 | ```javascript 622 | Azureservice.getCurrentUser(); 623 | ``` 624 | 625 | 626 | 627 | Azureservice.logout() 628 | ================= 629 | Logs out the current user. 630 | 631 | 632 | Parameters: 633 | --------------- 634 | 635 | None 636 | 637 | Returns 638 | ----------- 639 | Undefined 640 | 641 | Example 642 | ------------- 643 | ```javascript 644 | Azureservice.logout(); 645 | ``` 646 | 647 | 648 | Azureservice.isLoggedIn() 649 | ================= 650 | Checks if a user is currently logged in. 651 | 652 | 653 | Parameters: 654 | --------------- 655 | None 656 | 657 | Returns 658 | ----------- 659 | True if there is a current login session 660 | False if there is not 661 | 662 | Example 663 | ------------- 664 | ```javascript 665 | Azureservice.isLoggedIn(); 666 | ``` 667 | 668 | 669 | Azureservice.invokeApi(name, params) 670 | ================= 671 | Invoke a Azure Mobile service custom api call. 672 | 673 | [More information] (http://www.windowsazure.com/en-us/documentation/articles/mobile-services-windows-store-javascript-call-custom-api/) 674 | 675 | If this response from the api is not a status code 200 then it trigger the error function. 676 | 677 | Parameters: 678 | --------------- 679 | **name** Required 680 | 681 | ```` 682 | The custom API name 683 | ``` 684 | 685 | **params** 686 | 687 | ```` 688 | An object that contains a set of parameters to send the custom api. 689 | If no params object is set then it will default to calling the api with a GET method. 690 | 691 | Valid options to set in the params object: 692 | { 693 | method //String The method to call the api with. Valid options are get, post, put, delete 694 | body //Object of key/values pairs of data to send the request body 695 | parameters //Object of key/values pairs of data to send the query parameters 696 | headers //Object of key/values pairs of data to send in the reqeust headers 697 | } 698 | ``` 699 | 700 | Returns 701 | ----------- 702 | AngularJS Promise 703 | 704 | 705 | 706 | Example 707 | ------------- 708 | ```javascript 709 | Azureservice.invokeApi('apiName' { 710 | method: 'get', 711 | body: { 712 | ... 713 | } 714 | }) 715 | .then(function(response) { 716 | console.log('Here is my response object'); 717 | console.log(response) 718 | }, function(err) { 719 | console.error('Azure Error: ' + err); 720 | }); 721 | 722 | ``` 723 | 724 | 725 | 726 | 727 | 728 | ***For more information on Windows Azure Mobile service please refer to the*** [Microsoft Azure Mobile Service Documentation] (http://www.windowsazure.com/en-us/documentation/articles/mobile-services-html-how-to-use-client-library/) 729 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Terry Moore II", 3 | "name": "angular-azure-mobile-service", 4 | "description": "Angular Azure Mobile Service", 5 | "version": "1.3.11", 6 | "homepage": "https://github.com/TerryMooreII/angular-azure-mobile-service.git", 7 | "main": "./dist/angular-azure-mobile-service.min.js", 8 | "dependencies": { 9 | "angular": ">= 1.0.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /dist/angular-azure-mobile-service.js: -------------------------------------------------------------------------------- 1 | angular.module('azure-mobile-service.module', []).service('Azureservice', [ 2 | '$window', 3 | '$q', 4 | 'AzureMobileServiceClient', 5 | function Azureservice($window, $q, AzureMobileServiceClient) { 6 | 'use strict'; 7 | var VAILD_OAUTH_PROVIDERS = [ 8 | 'google', 9 | 'twitter', 10 | 'facebook', 11 | 'microsoftaccount', 12 | 'aad' 13 | ]; 14 | var MobileServiceClient; 15 | var client; 16 | var storage; 17 | var initMSClient = function () { 18 | if (isNullOrUndefined(AzureMobileServiceClient.API_URL)) { 19 | throw 'Angularservice: Unable to configure the MS Mobile Client. Missing API URL'; 20 | } 21 | var apiKey = AzureMobileServiceClient.API_KEY || null; 22 | MobileServiceClient = WindowsAzure.MobileServiceClient; 23 | client = new MobileServiceClient(AzureMobileServiceClient.API_URL, apiKey); 24 | }; 25 | var setStorage = function () { 26 | if (typeof AzureMobileServiceClient.STORAGE === 'string' && AzureMobileServiceClient.STORAGE.toLowerCase() === 'local') { 27 | storage = $window.localStorage; 28 | } else { 29 | storage = $window.sessionStorage; 30 | } 31 | }; 32 | var setCachedUser = function (user) { 33 | storage.loggedInUser = JSON.stringify(user); 34 | }; 35 | var setMSClientUser = function (user) { 36 | client.currentUser = user; 37 | }; 38 | var getCachedUser = function () { 39 | if (storage.loggedInUser) { 40 | client.currentUser = JSON.parse(storage.loggedInUser); 41 | } 42 | }; 43 | var getTable = function (tableName, withFilterFn) { 44 | if (typeof withFilterFn === 'function') 45 | return client.withFilter(withFilterFn).getTable(tableName); 46 | return client.getTable(tableName); 47 | }; 48 | var isUndefinedOrNotAnObjectOrFunction = function (obj) { 49 | return typeof obj === 'undefined' || typeof obj !== 'object' && typeof obj !== 'function'; 50 | }; 51 | var isUndefinedOrNotAnObject = function (obj) { 52 | return isNullOrUndefined(obj) || typeof obj !== 'object'; 53 | }; 54 | var isNullOrUndefined = function (value) { 55 | return value === null || typeof value === 'undefined'; 56 | }; 57 | var isNotNullOrUndefined = function (value) { 58 | return !isNullOrUndefined(value); 59 | }; 60 | //This will accept the Azure promise and turn it into a angular promise. 61 | //Elimiante the need for $scope.$apply in your controller. 62 | var wrapAzurePromiseWithAngularPromise = function (azurePromise) { 63 | var deferred = $q.defer(); 64 | azurePromise.done(function (items) { 65 | deferred.resolve(items); 66 | }, function (err) { 67 | deferred.reject(err); 68 | }); 69 | return deferred.promise; 70 | }; 71 | var init = function () { 72 | initMSClient(); 73 | setStorage(); 74 | getCachedUser(); 75 | }; 76 | //Initiate the service 77 | init(); 78 | return { 79 | query: function (tableName, obj, withFilterFn) { 80 | var data = null; 81 | if (isNullOrUndefined(tableName)) { 82 | console.error('Azureservice.query: You must specify a table name'); 83 | return null; 84 | } 85 | if (angular.isDefined(obj) && angular.isObject(obj)) { 86 | if (isUndefinedOrNotAnObjectOrFunction(obj.criteria)) { 87 | obj.criteria = {}; 88 | } 89 | data = getTable(tableName, withFilterFn); 90 | // Fetch system properties (if asked for) 91 | if (isNotNullOrUndefined(obj.systemProperties) && angular.isNumber(obj.systemProperties)) 92 | data.systemProperties = obj.systemProperties; 93 | data = data.where(obj.criteria, obj.params); 94 | //Number of results to return 95 | if (isNotNullOrUndefined(obj.take) && angular.isNumber(obj.take)) { 96 | data = data.take(obj.take); 97 | } 98 | //number of results to skip 99 | if (isNotNullOrUndefined(obj.skip) && angular.isNumber(obj.take)) { 100 | data = data.skip(obj.skip); 101 | } 102 | //How to sort/order the data 103 | if (angular.isDefined(obj.orderBy) && angular.isArray(obj.orderBy)) { 104 | var orderBy = obj.orderBy; 105 | for (var i = 0; i < orderBy.length; i++) { 106 | var column = orderBy[i].column; 107 | var dir = orderBy[i].direction; 108 | if (angular.isDefined(column)) { 109 | if (angular.isDefined(dir) && dir.toLowerCase() === 'desc') { 110 | data = data.orderByDescending(column); 111 | } else if (angular.isDefined(column)) { 112 | data = data.orderBy(column); 113 | } 114 | } 115 | } 116 | } 117 | //Return listed columns 118 | if (angular.isDefined(obj.columns) && angular.isArray(obj.columns)) { 119 | data = data.select(obj.columns.join()); 120 | } 121 | } else { 122 | //No criteria specified - get everything - Note azure limits the count of returned items see docs. 123 | data = getTable(tableName, withFilterFn).where({}); 124 | } 125 | return wrapAzurePromiseWithAngularPromise(data.includeTotalCount().read()); 126 | }, 127 | getById: function (tableName, id, withFilterFn) { 128 | if (isNullOrUndefined(tableName)) { 129 | console.error('Azureservice.getById: You must specify a table name'); 130 | return null; 131 | } 132 | if (isNullOrUndefined(id)) { 133 | console.error('Azureservice.getById: You must specify the id'); 134 | return null; 135 | } 136 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).lookup(id)); 137 | }, 138 | getAll: function (tableName, withFilterFn) { 139 | return this.query(tableName, null, withFilterFn); 140 | }, 141 | read: function (tableName, parameters, withFilterFn) { 142 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).read(parameters)); 143 | }, 144 | insert: function (tableName, obj, withFilterFn) { 145 | if (isNullOrUndefined(tableName)) { 146 | console.error('Azureservice.insert: You must specify a table name'); 147 | return null; 148 | } 149 | if (isUndefinedOrNotAnObject(obj)) { 150 | console.error('Azureservice.insert: You must specify the insert object'); 151 | return null; 152 | } 153 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).insert(obj)); 154 | }, 155 | update: function (tableName, obj, withFilterFn) { 156 | if (isNullOrUndefined(tableName)) { 157 | console.error('Azureservice.update: You must specify a table name'); 158 | return null; 159 | } 160 | if (isUndefinedOrNotAnObject(obj)) { 161 | console.error('Azureservice.update: You must specify the insert object'); 162 | return null; 163 | } 164 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).update(obj)); 165 | }, 166 | del: function (tableName, obj, withFilterFn) { 167 | if (isNullOrUndefined(tableName)) { 168 | console.error('Azureservice.del: You must specify a table name'); 169 | return null; 170 | } 171 | if (isUndefinedOrNotAnObject(obj)) { 172 | console.error('Azureservice.del: You must specify the insert object'); 173 | return null; 174 | } 175 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).del(obj)); 176 | }, 177 | login: function (oauthProvider, token) { 178 | if (!angular.isDefined(oauthProvider) || VAILD_OAUTH_PROVIDERS.indexOf(oauthProvider) === -1) { 179 | throw new Error('Azureservice.login Invalid or no oauth provider listed.'); 180 | } 181 | var promise = client.login(oauthProvider, token).then(function () { 182 | //cache login 183 | setCachedUser(client.currentUser); 184 | }); 185 | return wrapAzurePromiseWithAngularPromise(promise); 186 | }, 187 | setCurrentUser: function (currentUser) { 188 | if (angular.isDefined(currentUser) && angular.isObject(currentUser)) { 189 | setMSClientUser(currentUser); 190 | setCachedUser(currentUser); 191 | } 192 | }, 193 | getCurrentUser: function () { 194 | return client.currentUser; 195 | }, 196 | logout: function () { 197 | //clear cache 198 | storage.loggedInUser = null; 199 | client.logout(); 200 | }, 201 | isLoggedIn: function () { 202 | return isNotNullOrUndefined(client.currentUser) && isNotNullOrUndefined(storage.loggedInUser); 203 | }, 204 | invokeApi: function (name, options) { 205 | var deferred = $q.defer(); 206 | var validMethods = [ 207 | 'get', 208 | 'post', 209 | 'put', 210 | 'delete', 211 | 'patch' 212 | ]; 213 | if (isNullOrUndefined(name)) { 214 | console.error('Azureservice.invokeApi No custom api name specified'); 215 | return null; 216 | } 217 | if (isUndefinedOrNotAnObject(options)) { 218 | options = { method: 'get' }; 219 | } else if (isNullOrUndefined(options.method)) { 220 | options.method = 'get'; 221 | } else if (validMethods.indexOf(options.method.toLowerCase()) === -1) { 222 | console.error('Azureservice.invokeApi Invalid method type'); 223 | return null; 224 | } 225 | client.invokeApi(name, options).done(function (results) { 226 | deferred.resolve(results.result); 227 | }, function (err) { 228 | deferred.reject(err); 229 | }); 230 | return deferred.promise; 231 | } 232 | }; 233 | } 234 | ]); -------------------------------------------------------------------------------- /dist/angular-azure-mobile-service.min.js: -------------------------------------------------------------------------------- 1 | angular.module("azure-mobile-service.module",[]).service("Azureservice",["$window","$q","AzureMobileServiceClient",function(e,r,n){"use strict";var t,o,i,u=["google","twitter","facebook","microsoftaccount","aad"],s=function(){if(m(n.API_URL))throw"Angularservice: Unable to configure the MS Mobile Client. Missing API URL";var e=n.API_KEY||null;t=WindowsAzure.MobileServiceClient,o=new t(n.API_URL,e)},l=function(){i="string"==typeof n.STORAGE&&"local"===n.STORAGE.toLowerCase()?e.localStorage:e.sessionStorage},c=function(e){i.loggedInUser=JSON.stringify(e)},a=function(e){o.currentUser=e},f=function(){i.loggedInUser&&(o.currentUser=JSON.parse(i.loggedInUser))},d=function(e,r){return"function"==typeof r?o.withFilter(r).getTable(e):o.getTable(e)},g=function(e){return"undefined"==typeof e||"object"!=typeof e&&"function"!=typeof e},p=function(e){return m(e)||"object"!=typeof e},m=function(e){return null===e||"undefined"==typeof e},v=function(e){return!m(e)},y=function(e){var n=r.defer();return e.done(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},A=function(){s(),l(),f()};return A(),{query:function(e,r,n){var t=null;if(m(e))return console.error("Azureservice.query: You must specify a table name"),null;if(angular.isDefined(r)&&angular.isObject(r)){if(g(r.criteria)&&(r.criteria={}),t=d(e,n),v(r.systemProperties)&&angular.isNumber(r.systemProperties)&&(t.systemProperties=r.systemProperties),t=t.where(r.criteria,r.params),v(r.take)&&angular.isNumber(r.take)&&(t=t.take(r.take)),v(r.skip)&&angular.isNumber(r.take)&&(t=t.skip(r.skip)),angular.isDefined(r.orderBy)&&angular.isArray(r.orderBy))for(var o=r.orderBy,i=0;i= 1.0.0" 25 | }, 26 | "devDependencies": { 27 | "gulp": "~3.8.11", 28 | "gulp-rename": "~1.2.0", 29 | "gulp-concat": "~2.4.3", 30 | "gulp-uglify": "~1.1.0", 31 | "gulp-jshint": "~1.9.2", 32 | "gulp-ngmin": "~0.3.0", 33 | "express": "~4.11.2", 34 | "connect-livereload": "~0.5.2", 35 | "tiny-lr": "~0.1.5" 36 | }, 37 | "autoupdate": { 38 | "source": "git", 39 | "target": "https://github.com/TerryMooreII/angular-azure-mobile-service.git", 40 | "basePath": "dist", 41 | "files": [ 42 | "angular-azure-mobile-service.js", 43 | "angular-azure-mobile-service.min.js" 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/angular-azure-mobile-service.js: -------------------------------------------------------------------------------- 1 | angular.module('azure-mobile-service.module', []) 2 | .service('Azureservice', ['$window', '$q', 'AzureMobileServiceClient', function Azureservice($window, $q, AzureMobileServiceClient) { 3 | 4 | 'use strict'; 5 | 6 | var VAILD_OAUTH_PROVIDERS = ['google', 'twitter', 'facebook', 'microsoftaccount', 'aad']; 7 | 8 | var MobileServiceClient; 9 | var client; 10 | var storage; 11 | 12 | var initMSClient = function() { 13 | 14 | if (isNullOrUndefined(AzureMobileServiceClient.API_URL)) { 15 | throw ('Angularservice: Unable to configure the MS Mobile Client. Missing API URL'); 16 | } 17 | 18 | var apiKey = AzureMobileServiceClient.API_KEY || null; 19 | 20 | MobileServiceClient = WindowsAzure.MobileServiceClient; 21 | client = new MobileServiceClient(AzureMobileServiceClient.API_URL, apiKey); 22 | }; 23 | 24 | var setStorage = function() { 25 | if (typeof AzureMobileServiceClient.STORAGE === 'string' && AzureMobileServiceClient.STORAGE.toLowerCase() === 'local') { 26 | storage = $window.localStorage; 27 | } else { 28 | storage = $window.sessionStorage; 29 | } 30 | }; 31 | 32 | var setCachedUser = function(user) { 33 | storage.loggedInUser = JSON.stringify(user); 34 | }; 35 | 36 | var setMSClientUser = function(user) { 37 | client.currentUser = user; 38 | }; 39 | 40 | var getCachedUser = function() { 41 | if (storage.loggedInUser) { 42 | client.currentUser = JSON.parse(storage.loggedInUser); 43 | } 44 | }; 45 | 46 | var getTable = function(tableName, withFilterFn) { 47 | 48 | if (typeof withFilterFn === 'function') 49 | return client.withFilter(withFilterFn).getTable(tableName); 50 | 51 | return client.getTable(tableName); 52 | }; 53 | 54 | var isUndefinedOrNotAnObjectOrFunction = function(obj) { 55 | return typeof obj === 'undefined' || (typeof obj !== 'object' && typeof obj !== 'function'); 56 | }; 57 | 58 | var isUndefinedOrNotAnObject = function(obj) { 59 | return isNullOrUndefined(obj) || (typeof obj !== 'object'); 60 | }; 61 | 62 | var isNullOrUndefined = function(value) { 63 | return value === null || typeof value === 'undefined'; 64 | }; 65 | 66 | var isNotNullOrUndefined = function(value) { 67 | return !isNullOrUndefined(value); 68 | }; 69 | 70 | //This will accept the Azure promise and turn it into a angular promise. 71 | //Elimiante the need for $scope.$apply in your controller. 72 | var wrapAzurePromiseWithAngularPromise = function(azurePromise) { 73 | var deferred = $q.defer(); 74 | 75 | azurePromise 76 | .done(function(items) { 77 | deferred.resolve(items); 78 | }, 79 | function(err) { 80 | deferred.reject(err); 81 | }); 82 | return deferred.promise; 83 | }; 84 | 85 | var init = function() { 86 | initMSClient(); 87 | setStorage(); 88 | getCachedUser(); 89 | }; 90 | 91 | //Initiate the service 92 | init(); 93 | 94 | return { 95 | /* 96 | The query method will create and return an azure query. 97 | 98 | @param string tableName REQUIRED The name of the table to query 99 | @param object obj 100 | @param obj or function criteria The search object or a function to filter 101 | If function then it must be an OData predicate. 102 | @param array params Array of parameters to pass the criteria function 103 | @param array columns Array of column names to return 104 | @param int take Number of results to return 105 | @param int skip Number of reuslts to skip over 106 | @param array orderBy Array of objects 107 | @param string column Column name to sort by 108 | @param string direction Direction to sort asc || desc 109 | @param function withFilterFn OPTIONAL A function that can read and write arbitrary properties or add additional headers to the request 110 | @return promise Returns a WindowsAzure promise 111 | */ 112 | query: function(tableName, obj, withFilterFn) { 113 | 114 | var data = null; 115 | 116 | if (isNullOrUndefined(tableName)) { 117 | console.error('Azureservice.query: You must specify a table name'); 118 | return null; 119 | } 120 | 121 | if (angular.isDefined(obj) && angular.isObject(obj)) { 122 | 123 | if (isUndefinedOrNotAnObjectOrFunction(obj.criteria)) { 124 | obj.criteria = {}; 125 | } 126 | 127 | data = getTable(tableName, withFilterFn); 128 | 129 | // Fetch system properties (if asked for) 130 | if (isNotNullOrUndefined(obj.systemProperties) && angular.isNumber(obj.systemProperties)) 131 | data.systemProperties = obj.systemProperties; 132 | 133 | data = data.where(obj.criteria, obj.params); 134 | 135 | //Number of results to return 136 | if (isNotNullOrUndefined(obj.take) && angular.isNumber(obj.take)) { 137 | data = data.take(obj.take); 138 | } 139 | 140 | //number of results to skip 141 | if (isNotNullOrUndefined(obj.skip) && angular.isNumber(obj.take)) { 142 | data = data.skip(obj.skip); 143 | } 144 | 145 | //How to sort/order the data 146 | if (angular.isDefined(obj.orderBy) && angular.isArray(obj.orderBy)) { 147 | var orderBy = obj.orderBy; 148 | 149 | for (var i = 0; i < orderBy.length; i++) { 150 | var column = orderBy[i].column; 151 | var dir = orderBy[i].direction; 152 | 153 | if (angular.isDefined(column)) { 154 | if (angular.isDefined(dir) && dir.toLowerCase() === 'desc') { 155 | data = data.orderByDescending(column); 156 | } else if (angular.isDefined(column)) { 157 | data = data.orderBy(column); 158 | } 159 | } 160 | } 161 | } 162 | 163 | //Return listed columns 164 | if (angular.isDefined(obj.columns) && angular.isArray(obj.columns)) { 165 | data = data.select(obj.columns.join()); 166 | } 167 | 168 | } else { 169 | //No criteria specified - get everything - Note azure limits the count of returned items see docs. 170 | data = getTable(tableName, withFilterFn).where({}); 171 | } 172 | 173 | return wrapAzurePromiseWithAngularPromise(data.includeTotalCount().read()); 174 | }, 175 | 176 | /* 177 | Get single item in Azure 178 | 179 | @param string tableName REQUIRED The name of the table to query 180 | @param string id REQUIRED String id of the item to get 181 | @param function withFilterFn OPTIONAL A function that can read and write arbitrary properties or add additional headers to the request 182 | @return promise Returns a WindowsAzure promise 183 | */ 184 | getById: function(tableName, id, withFilterFn) { 185 | if (isNullOrUndefined(tableName)) { 186 | console.error('Azureservice.getById: You must specify a table name'); 187 | return null; 188 | } 189 | 190 | if (isNullOrUndefined(id)) { 191 | console.error('Azureservice.getById: You must specify the id'); 192 | return null; 193 | } 194 | 195 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).lookup(id)); 196 | }, 197 | 198 | /* 199 | Alias to .query(tableName, null, withFilterFn) 200 | Returns all results 201 | */ 202 | getAll: function(tableName, withFilterFn) { 203 | return this.query(tableName, null, withFilterFn); 204 | }, 205 | 206 | /* 207 | Execute read-query in Azure 208 | 209 | @param string tableName REQUIRED The name of the table to query 210 | @param object parameters OPTIONAL An object of user-defined parameters and values to include in the request URI query string 211 | @param function withFilterFn OPTIONAL A function that can read and write arbitrary properties or add additional headers to the request 212 | @return promise Returns a WindowsAzure promise 213 | */ 214 | read: function(tableName, parameters, withFilterFn) { 215 | 216 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).read(parameters)); 217 | }, 218 | 219 | /* 220 | Insert row in to Azure 221 | 222 | @param string tableName REQUIRED The name of the table to query 223 | @param object obj REQUIRED A JSON object of data to insert into the database 224 | @param function withFilterFn OPTIONAL A function that can read and write arbitrary properties or add additional headers to the request 225 | @return promise Returns a WindowsAzure promise 226 | */ 227 | 228 | insert: function(tableName, obj, withFilterFn) { 229 | if (isNullOrUndefined(tableName)) { 230 | console.error('Azureservice.insert: You must specify a table name'); 231 | return null; 232 | } 233 | 234 | if (isUndefinedOrNotAnObject(obj)) { 235 | console.error('Azureservice.insert: You must specify the insert object'); 236 | return null; 237 | } 238 | 239 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).insert(obj)); 240 | }, 241 | 242 | /* 243 | Update row in Azure 244 | 245 | @param string tableName REQUIRED The name of the table to query 246 | @param object obj REQUIRED A JSON object of data to update into the database 247 | @param function withFilterFn OPTIONAL A function that can read and write arbitrary properties or add additional headers to the request 248 | @return promise Returns a WindowsAzure promise 249 | */ 250 | 251 | update: function(tableName, obj, withFilterFn) { 252 | if (isNullOrUndefined(tableName)) { 253 | console.error('Azureservice.update: You must specify a table name'); 254 | return null; 255 | } 256 | 257 | if (isUndefinedOrNotAnObject(obj)) { 258 | console.error('Azureservice.update: You must specify the insert object'); 259 | return null; 260 | } 261 | 262 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).update(obj)); 263 | }, 264 | 265 | /* 266 | Delete row(s) from Azure 267 | 268 | @param string tableName REQUIRED The name of the table to query 269 | @param object obj REQUIRED A JSON object of data to query for deletion from the database 270 | @param function withFilterFn OPTIONAL A function that can read and write arbitrary properties or add additional headers to the request 271 | @return promise Returns a WindowsAzure promise 272 | */ 273 | 274 | del: function(tableName, obj, withFilterFn) { 275 | if (isNullOrUndefined(tableName)) { 276 | console.error('Azureservice.del: You must specify a table name'); 277 | return null; 278 | } 279 | 280 | if (isUndefinedOrNotAnObject(obj)) { 281 | console.error('Azureservice.del: You must specify the insert object'); 282 | return null; 283 | } 284 | 285 | return wrapAzurePromiseWithAngularPromise(getTable(tableName, withFilterFn).del(obj)); 286 | }, 287 | 288 | /* 289 | Logs a user into the oauthProvider service using Windows Azure 290 | Stores the data in sessionStorage for future queries 291 | 292 | @param string oauthProvider REQUIRED Pass in an OAuth provider name (google, facebook, etc) 293 | @param string token OPTIONAL An existing authentication token to login to the OAuth provider with 294 | @return promise Returns a WindowsAzure promise 295 | */ 296 | 297 | login: function(oauthProvider, token) { 298 | 299 | if (!angular.isDefined(oauthProvider) || VAILD_OAUTH_PROVIDERS.indexOf(oauthProvider) === -1) { 300 | throw new Error('Azureservice.login Invalid or no oauth provider listed.'); 301 | } 302 | 303 | var promise = client.login(oauthProvider, token).then(function() { 304 | //cache login 305 | setCachedUser(client.currentUser); 306 | }); 307 | 308 | return wrapAzurePromiseWithAngularPromise(promise); 309 | }, 310 | 311 | 312 | /* 313 | Sets the logged in user. Used when using azure custom authentication 314 | @param object user REQUIRED user object 315 | */ 316 | 317 | setCurrentUser: function(currentUser) { 318 | 319 | if (angular.isDefined(currentUser) && angular.isObject(currentUser)) { 320 | setMSClientUser(currentUser); 321 | setCachedUser(currentUser); 322 | } 323 | 324 | }, 325 | 326 | /* 327 | Gets the logged in user. 328 | 329 | @return The user logged in to Azure, or null if not logged in. 330 | */ 331 | 332 | getCurrentUser: function() { 333 | 334 | return client.currentUser; 335 | 336 | }, 337 | 338 | /* 339 | Logs a user out 340 | */ 341 | 342 | logout: function() { 343 | //clear cache 344 | storage.loggedInUser = null; 345 | client.logout(); 346 | }, 347 | 348 | isLoggedIn: function() { 349 | return isNotNullOrUndefined(client.currentUser) && isNotNullOrUndefined(storage.loggedInUser); 350 | }, 351 | 352 | /* 353 | @param string name the custom api name 354 | @param object options 355 | @param string method required get, post, put, delete 356 | @param object body key/value to send in the request body 357 | @param object headers key value to send in the headers 358 | @param object parameters key/value to send as parameters 359 | 360 | */ 361 | 362 | invokeApi: function(name, options) { 363 | 364 | var deferred = $q.defer(); 365 | 366 | var validMethods = ['get', 'post', 'put', 'delete', 'patch']; 367 | 368 | if (isNullOrUndefined(name)) { 369 | console.error('Azureservice.invokeApi No custom api name specified'); 370 | return null; 371 | } 372 | 373 | if (isUndefinedOrNotAnObject(options)) { 374 | options = { 375 | method: 'get' 376 | }; 377 | } else if (isNullOrUndefined(options.method)) { 378 | options.method = 'get'; 379 | } else if (validMethods.indexOf(options.method.toLowerCase()) === -1) { 380 | console.error('Azureservice.invokeApi Invalid method type'); 381 | return null; 382 | } 383 | 384 | 385 | client 386 | .invokeApi(name, options) 387 | .done(function(results) { 388 | deferred.resolve(results.result); 389 | }, 390 | function(err) { 391 | deferred.reject(err); 392 | }); 393 | 394 | return deferred.promise; 395 | } 396 | }; 397 | 398 | }]); --------------------------------------------------------------------------------