AngularJS: server communication

33
AngularJS Server Communication

Transcript of AngularJS: server communication

Page 1: AngularJS: server communication

AngularJS Server Communication

Page 2: AngularJS: server communication

Intro

● AngularJS web apps sono interamente client-side applications!

● Senza un back end saremmo limitati a mostrare e utilizzare solo le info presenti a load time.

● Angularjs fornisce servizi per la comunicazione con il server:o $http;o $resource;

● Ci sono inoltre servizi di terze parti: o restangular

Page 3: AngularJS: server communication

$http

$http è un servizio che facilita la comunicazione con il server via● XMLHttpRequest;● JSONP.

E’ un wrapper del XMLHttpRequest object.

Page 4: AngularJS: server communication

$http // Simple GET request example

$http({

method: 'GET',

url: '/api/users'

})

.success(function(data, status, headers, config) {

// this callback will be called asynchronously when the response is available

})

.error(function(data, status, headers, config) {

// called asynchronously if an error occurs or server returns response with an error status

});

// Simple GET request example

$http({

method: 'GET',

url: '/api/users'

})

.then(function(resp) {

// resp is response object

}, function(resp){

// resp with error

});

Page 5: AngularJS: server communication

$http - Shortcut Methods

● geto $http.get('/someUrl', config)

● posto $http.post('/someUrl', someObject,

config)● delete

o $http.delete('/someUrl', config)● ...

Page 6: AngularJS: server communication

$http - Config

● {params: {param1:value, .., paramN:value}} ● {cache: boolean}● …..

// Simple GET request example

$http.get('/api/getUser’, {params: {id: $idUtente}})

.success(function(data, status, headers, config) {

})

.error(function(data, status, headers, config) {

});

Page 7: AngularJS: server communication

$http - Cache

Di default il servizio $http non usa la cache.E’ possibile impostare la cache per ● request

o $http.get('/api/getUser’, {cache: true})

● per applicazioneo .config(function($httpProvider, $cacheFactory) {

$httpProvider.defaults.cache = true }

Default cache: $cacheFactory

Page 8: AngularJS: server communication

$http - Custom Cache

// Custom cache request example

var lru = $cacheFactory('lru', {

capacity: 20

});

// $http request

$http.get('/api/users', { cache: lru })

.success(function(data) {})

.error(function(data) {});

// Custom cache config example

angular.module('myApp')

.config(function($httpProvider, $cacheFactory) {

$httpProvider.defaults.cache =

$cacheFactory('lru', {

capacity: 20

});

});

Page 9: AngularJS: server communication

Web App sempre più RESTful

● L’approccio REST è venuto alla ribalta negli ultimi anni ed è attualmente molto usato

● RESTful VS. SOAP - REST propone una visione del Web incentrata sul concetto di risorsa mentre i SOAP Web Service mettono in risalto il concetto di servizio.

● Angularjs propone il servizio $resource

Page 10: AngularJS: server communication

RESTful

● Apparso la prima volta nel 2000 nella tesi di Roy Fielding

● Definisce una serie di principi:o Identificazione delle risorseo Utilizzo esplicito dei metodi HTTPo Risorse autodescrittiveo Collegamenti tra risorseo Comunicazione senza stato

● Il WWW è un esempio concreto di questi principi

Page 11: AngularJS: server communication

Servizi RESTful

● In una architettura REST è definita una mappatura uno ad uno tra le tipiche operazioni CRUD e i metodi httpo POST - Createo GET - Reado PUT - Updateo DELETE - Delete

● Un oggetto è identificabile univocamente attraverso una URI● Nessun vincolo sulle modalità di rappresentazione di una risorsa● Diversi formati di rappresentazione: XML, JSON, HTML, … .

Page 12: AngularJS: server communication

$resource

$resource è una factory che incapsula i servizi $http e aggiunge supporto per l’interazione con i servizi RESTful server-side

Richiede● L’importazione della lib angular-resource.js● La definizione della dipendenza dal modulo ngResource

o angular.module('myApp', ['ngResource']);

Page 13: AngularJS: server communication

$resourceSintassi

$resource(url, [paramDefaults], [actions], options);

Dove:● url può essere parametrizzato mediante il simbolo : Es:

https://api.mongolab.com/api/1/databases/angworkshop/collections/contatto/:id

● actions è un hash che permette di indicare comportamenti custom che estendono le action di default di resource.

{action1: {method:?, params:?, isArray:?,

headers:?, ...},

action2: {method:?, params:?, isArray:?,

headers:?, ...},

...}

Page 14: AngularJS: server communication

$resource - [actions]

● action – {string} – Nome dell’azione

● method – {string} – Case insensitive HTTP method (e.g. GET, POST, PUT, DELETE, JSONP,

etc).

● params – {Object} – Set opzionale di parametri..

● isArray – {boolean} – True se il result è un array

● ...

{action1: {method:?, params:?, isArray:?, headers:?, ...},

action2: {method:?, params:?, isArray:?, headers:?, ...},

...}

Page 15: AngularJS: server communication

$resource - EXAMPLE

// DefinizionecontattoModel.factory('Contatto', ['$resource', function($resource){ return $resource('https://api.mongolab.com/api/1/databases/angworkshop/collections/contatto/:id', {}, {

// actions show: { method: 'GET', params: {apiKey:'WLKPfaC3ztzHpxYtyTD85D7-7iXaO4dj', id: '@id'} }, update: { method: 'PUT', params: {apiKey:'WLKPfaC3ztzHpxYtyTD85D7-7iXaO4dj', id: '@id'} }, delete: { method: 'DELETE', params: {apiKey:'WLKPfaC3ztzHpxYtyTD85D7-7iXaO4dj', id: '@id'} }, create: { method: 'POST', params: {apiKey:'WLKPfaC3ztzHpxYtyTD85D7-7iXaO4dj'} }

});

}]);

Page 16: AngularJS: server communication

$resource - EXAMPLE

// UsoContatto.create($scope.contatto, function(response){ // success console.log('Successo', response); $scope.showSuccess = true;},function(response){ // error console.log('Error', response); $scope.showDanger = true;});

// Uso con $promiseContatto.create($scope.contatto) .$promise .then(function(response) { // success console.log('Successo', response); $scope.showSuccess = true;

}) .then(function(response) { // error tconsole.log('Error', response); $scope.showDanger = true });

Page 17: AngularJS: server communication

$resource - Cache

Analoga alla cache $http. Può assumere i valori:● false/true - $cacheFactory● custom cache

Page 18: AngularJS: server communication

Restangular

Libreria esterna.Si propone di rendere ancora più semplice la comunicazione con il mondo esterno.Richiede● L’importazione della lib restangular.js● La definizione della dipendenza dal modulo restangular

o angular.module('myApp', ['restangular']);

Page 19: AngularJS: server communication

Perché RestangularThe idea is that Restangular can also handle all of your URLs, so that you don't have to know anything about them.

Suppose that you have something like this for cars : /users/123/cars/456

In $resource, You'd have to construct that URL manually and you'd also have to construct the $resource object for this manually.

Restangular helps you in this by "remembering" the URLs.

So if you do in some place

Restangular.one("users", 123).get().then(function(user) {

$scope.user = user; }); // Some other code //Automatically does the request

to /users/123/cars as it remembers in which object you're asking it.

$scope.user.getList('cars')

Martin Gontovnikas www.stackoverflow.com

Page 20: AngularJS: server communication

Approfondimenti: promise

Contesto: ● chiamate asincrona

Alternative● callback

Page 21: AngularJS: server communication

Approfondimenti: promise// Callback example

asyncCall(function(err, data1){

if(err) return callback(err);

anotherAsyncCall(function(err2, data2){

if(err2) return calllback(err2);

oneMoreAsyncCall(function(err3,

data3){

if(err3) return callback(err3);

// and so on

});

});

});

Problemi callback:● una scarsa leggibilità del

codice● difficoltà di composizione delle

callback● difficoltà di gestione degli errori

e di debug

Page 22: AngularJS: server communication

Approfondimenti: promise

Sono oggetti che rappresentano il risultato di una chiamata di funzione asincrona.

Stato:

● pending è lo stato in cui non è stato ancora ottenuto il risultato della chiamata asincrona

● resolved in questo stato la chiamata asincrona ha prodotto un risultato

● rejected rappresenta la situazione in cui non è possibile ottenere un risultato dalla chiamata asincrona, eventualmente per il verificarsi di una condizione d’errore

Page 23: AngularJS: server communication

Approfondimenti: promise

// promise example

asyncCall()

.then(function(data1){

// do something...

return anotherAsyncCall();

})

.then(function(data2){

// do something...

return oneMoreAsyncCall();

}).fail(function(err) {

// handle any error resulting from any of the

above calls

})

.done();

Non nativamente supportate da javascript

Bisogna utilizzare la libreria “Q”

Vantaggi:● codice più leggibile

Page 24: AngularJS: server communication

Approfondimenti: XMLHttpRequest

● Insieme di API Javascript disegnato da Microsoft e adottato da Google, Apple e Mozilla

● Consentono di scambiare dati con il server senza dover ricaricare l’intera pagina

● A discapito del nome può essere usato per recuperare diversi formati di file (es. JSON)

Page 25: AngularJS: server communication

Approfondimenti: JSON

Acronimo di JavaScript Object Notation, è un formato adatto all'interscambio di dati fra applicazioni client-server

// JSON example

{name1: value, name2: [{nameAr1: value}, {nameAr2:value}]}

Page 26: AngularJS: server communication

Approfondimenti: JSONP

Same-domain-policy impedisce a script scaricati dalla rete di accedere, tramite qualsiasi tipo di richiesta HTTP, a risorse che si trovano su server diversi rispetto a quello iniziale che ha inviato lo script.

JSONP Acronimo di JavaScript Object Notation with Padding è una tecnica che permette di ovviare a questa limitazione permettendo a un browser di accedere, ovviamente con alcuni limiti, a risorse remote indipendentemente dall’host di origine.

Page 27: AngularJS: server communication

Approfondimenti: Service, Factory e Provider

● I tre servizi sono in realtà un unico servizio: provider

● factory e service sono implementazioni differenti di provider

● vengono registrati come singleton all'interno dell'applicazione AngularJS

Page 28: AngularJS: server communication

ServiceDal punto di vista sintattico un Services restituisce un oggetto singleton che rimane in vita fino alla chiusura del browser. Sintassi:

mymodule.service('serviceName', function([d1,...,dn]))

dove● function([d1,..,dn]) è il costruttore della funzione che verrà istanziata;● e [d1,...,dn] è un array di 0 o più dipendenze.

.

Page 29: AngularJS: server communication

Service - Example

La più semplice implementazione di provider, rappresenta l'istanza di una funzione creata usando l'operatore new

angular.module(‘app', [])

.service(‘myService’, function(a){

...

}]);

Angular lo inizializza così: var myServiceSingleton = new myService();

Page 30: AngularJS: server communication

FactoryUna Factory è una funzione responsabile della creazione di un nuovo Servizio.La sintassi per definire una Factory è la seguente

mymodule.factory(“serviceID”, function([d1,...,dn]))

dove● function([d1,...,dn]) è la funzione che angular richiamerà per creare una nuova

istanza del servizio;● e [d1,...,dn] è un array di 0 o più dipendenze.

Un classico esempio d’uso di una Factory è per creare un nuovo servizio che dipende da $resource.

Page 31: AngularJS: server communication

Factory - Example

angular.module('app',[])

.factory('myFactory', ['d1', function(d1){

return Service()

}]);

Angular lo inizializza così: var myFactorySingleton = myFactory();

Page 32: AngularJS: server communication

ProviderIl provider è definito come un tipo custom configurabile in fase di configurazione che implementa il metodo $get. Questo metodo altro non è che una funzione Factory.La sintassi per definire un provider è la seguente:

mymodule.provider(“providerName”, function([d1,...,dn]))

dove● f([d1,...,dn]) è una funzione che crea una nuova istanza di un servizio;● e [d1,...,dn] è un array di 0 o più dipendenze.

Nel pratico una funzione Provider è utile per isolare il Service creato dal resto dell’applicazione e consentire l’intercambiabilità di Service che implementano la stessa interfaccia o il comportamento dello stesso in modo configurabile e trasparente per il resto dell’applicazione.

Page 33: AngularJS: server communication

Provider - Exampleangular.module('app',[]).provider('myProvider', function() {

var PREFIX = 'https://api.mongolab.com/api/angworkshop/collections/';

// API accessibili in fase di configurazione

this.setPrefix = function setPrefix(value) {

PREFIX = value;

};

this.$get = function myProviderFactory() {

return return {

say = function say(msg) {

return PREFIX + msg;

}

};

};});Angular lo inizializza così var myProviderSingleton = myProvider();