¡Esta es una revisión vieja del documento!
Tabla de Contenidos
10.7 remoteResource
Ya tenemos un API REST funcionando en el servidor, así que vamos a volver a la parte de AngularJS para por fin tener una aplicación funcionando capaz de hacer un CRUD.
remoteResource
Lo primero es acabar el servicio remoteResource para que haga uso del API REST que hemos creado.El servicio se basa en la función RemoteResource que es la que tiene toda la funcionalidad , la hemos modificado para que los 2 métodos que ya hay hagan uso del API REST.
function RemoteResource($http, $q, baseUrl) {
this.get = function(idSeguro) {
var defered = $q.defer();
var promise = defered.promise;
$http({
method: 'GET',
url: baseUrl + '/api/SeguroMedico/' + idSeguro
}).success(function(data, status, headers, config) {
defered.resolve(data);
}).error(function(data, status, headers, config) {
if (status === 400) {
defered.reject(data);
} else {
throw new Error("Fallo obtener los datos:" + status + "\n" + data);
}
});
return promise;
};
this.list = function() {
var defered = $q.defer();
var promise = defered.promise;
$http({
method: 'GET',
url: baseUrl + '/api/SeguroMedico'
}).success(function(data, status, headers, config) {
defered.resolve(data);
}).error(function(data, status, headers, config) {
if (status === 400) {
defered.reject(data);
} else {
throw new Error("Fallo obtener los datos:" + status + "\n" + data);
}
});
return promise;
};
}
- Linea 31: Hemos puesto la URL correcta para acceder al servidor, incluyendo el valor del
idSeguroy así obtener solo un seguro médico. - Línea 12: Vamos ahora a tratar de forma distinta si se ha retornado un 400 o cualquier otra cosa.
- Línea 13: Si se ha retornado un 400, lo que hay en data es un array de objetos
BussinessMessagey es lo que retornamos como resultado de rechazar la promesa. Notar que ahora hemos cambiado el interzaf de la promesa. Cuando es rechazada se retorna un array de objetosBussinessMessage. - Línea 15: En caso de que no sea un 400, será algún error del servidor, así que lanzamos un error de JavaScript ya que lo que ocurrió en el servidor fue un error así que aquí seguimos tratándolo como un error.
- Linea 29: Hemos puesto la URL correcta para acceder al servidor para poder obtener todos los seguros médicos.
- Línea 33: Vamos ahora a tratar de forma distinta si se ha retornado un 400 o cualquier otra cosa.
- Línea 34: Si se ha retornado un 400, lo que hay en data es un array de objetos
BussinessMessagey es lo que retornamos como resultado de rechazar la promesa. Notar que ahora hemos cambiado el interzaf de la promesa. Cuando es rechazada se retorna un array de objetosBussinessMessage. - Línea 36: En caso de que no sea un 400, será algún error del servidor, así que lanzamos un error de JavaScript ya que lo que ocurrió en el servidor fue un error así que aquí seguimos tratándolo como un error.
Como vemos los cambios han sido mínimos, solo la nueva URL y la gestión del error 400 Bad Request que ahora es lo que hace que se rechace la promesa.
Pasemos ahora a ver el resto de los métodos. Son casi todos iguales y solo cambia la URL y los datos que se envían.
this.insert = function(seguroMedico) {
var defered = $q.defer();
var promise = defered.promise;
$http({
method: 'POST',
url: baseUrl + '/api/SeguroMedico',
data: seguroMedico
}).success(function(data, status, headers, config) {
defered.resolve(data);
}).error(function(data, status, headers, config) {
if (status === 400) {
defered.reject(data);
} else {
throw new Error("Fallo obtener los datos:" + status + "\n" + data);
}
});
return promise;
};
this.update = function(idSeguro, seguroMedico) {
var defered = $q.defer();
var promise = defered.promise;
$http({
method: 'PUT',
url: baseUrl + '/api/SeguroMedico/' + idSeguro,
data: seguroMedico
}).success(function(data, status, headers, config) {
defered.resolve(data);
}).error(function(data, status, headers, config) {
if (status === 400) {
defered.reject(data);
} else {
throw new Error("Fallo obtener los datos:" + status + "\n" + data);
}
});
return promise;
};
this.delete = function(idSeguro) {
var defered = $q.defer();
var promise = defered.promise;
$http({
method: 'DELETE',
url: baseUrl + '/api/SeguroMedico/' + idSeguro
}).success(function(data, status, headers, config) {
defered.resolve(data);
}).error(function(data, status, headers, config) {
if (status === 400) {
defered.reject(data);
} else {
throw new Error("Fallo obtener los datos:" + status + "\n" + data);
}
});
return promise;
};
- Líneas 8 y 29: Se usa la propiedad
data. La propiedaddatacontiene el objeto JavaScript que se transforma en un String JSON y se envía en la petición HTTP en el cuerpo de la misma. Esta String JSON es el que posteriormente se obtiene desde el servidor en Java con la anotación @RequestBody. - Línea 22: Hemos optado por pasar el parámetro
idSeguroaunque también se podría obtener del mismo objeto JavaScriptseguroMedicomedianteseguroMedico.idSeguro. Se ha hecho así para destacar en el update se envía elidSegurotanto en la URL como en el propio objeto.
Aunque nuestra clase funcione perfectamente, estas 2 últimas disponen de muchas mas funcionalidades con lo que deberías usarse en proyectos reales y decir que el equipo de AngularJS está trabajando en mejorar aun mas su clase $resource.
Aun así nuestra clase remoteResource ha cumplido perfectamente su papel para entender como funciona todo.
La aplicación
Como ya tenemos acabado el servicio remoteResource ya podemos modificar la aplicación para poder hacer las siguientes operaciones:
- Borrar un seguro médico
- Actualizar los datos de un seguro médico
- Añadir un nuevo seguro médico
Borrar seguro médico
Para borrar un seguro médico vamos a añadir un botón de borrado en la tabla en la que se muestran todos los seguros médicos. Estebotón llamará a una función del $scope que es la que realizará la tarea.
<table>
<thead>
<tr>
<th>NIF</th>
<th>Nombre</th>
<th>Apellido</th>
<th>Sexo</th>
<th>Accion</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3">El Nº de seguros medicos es:</td>
<td ng-bind="seguros.length"></td>
</tr>
</tfoot>
<tbody>
<tr ng-repeat="seguro in seguros| filteri18n:{ape1:filtro.ape1}" ng-style="{color:($odd?'red':'green')}">
<td><a ng-href="#/seguro/edit/{{seguro.idSeguro}}">{{seguro.nif}}</a></td>
<td>{{seguro.nombre}}</td>
<td>{{seguro.ape1}}</td>
<td ng-switch on="seguro.sexo">
<span ng-switch-when="H">Hombre</span>
<span ng-switch-when="M">Mujer</span>
<span ng-switch-when=""></span>
<span ng-switch-default>Desconocido</span>
</td>
<td>
<button ng-click="borrar(seguro.idSeguro)">Borrar</button>
</td>
</tr>
</tbody>
</table>
- Linea 8: Nueva columna con las acciones a realizar para cada seguro médico
- Línea 29: Añadimos u nuevo botón que al pulsarlo llama a la función
borrar(idSeguro). Vemos como al usar la expresiónseguro.idSegurono es ncesario usar las llaves $$10_servidor ya que estmaos en una expresión que es de JavaScript.
El controlador ListadoSeguroController con el nuevo método borrar(idSeguro) queda de la siguiente forma:
app.controller("ListadoSeguroController", ['$scope', 'seguros', 'remoteResource', function($scope, seguros, remoteResource) {
$scope.seguros = seguros;
$scope.borrar = function(idSeguro) {
remoteResource.delete(idSeguro).then(function() {
remoteResource.list().then(function(seguros) {
$scope.seguros = seguros;
});
});
};
}]);
- Linea 1: Inyectamos el servicio
remoteResourceya que nos va a hacer falta. - Línea 5: Llamamos al método
deletepara borrar el seguro médico cuya clave sea el parámetroidSeguro. - Línea 6: Si se ha borrado correctamente el seguro médico, volvemos a llamar al método
listpara obtenga otra vez los seguros de la base de datos y se refresque la tabla y se vea el seguro borrado en la pantalla. En vez de hacer una llamada a la base de datos podríamos optimizarlo borrando el elemento directamente del array.
Actualizar los datos de un seguro médico
Vamos ahora actualizar los datos de un seguro médico que ya existe. Lo primera que vamos a hacer es cambiar el nombre del controlador DetalleSeguroController a EditSeguroController ya que así queda mas claro que vamos a editar los datos del seguro médico.
Lo único que vamos a hacer es modificar la función guardar para que finalmente llame a la base de datos.
app.controller("EditSeguroController", ['$scope', 'seguro', 'remoteResource', '$location', function($scope, seguro, remoteResource, $location) {
$scope.filtro = {
ape1: ""
};
$scope.sexos = [{
codSexo: "H",
descripcion: "Hombre"
}, {
codSexo: "M",
descripcion: "Mujer"
}];
$scope.seguro = seguro;
$scope.guardar = function() {
if ($scope.form.$valid) {
remoteResource.update($scope.seguro.idSeguro, $scope.seguro).then(function() {
$location.path("/seguro/listado");
});
} else {
alert("Hay datos inválidos");
}
};
}]);
- Linea 1: Hemos cambiado el nombre del controlador y también inyectamos los servicios $locate y
remoteResourceque usaremos en el controlador. - Línea 15: Hemos borrado la creación del objeto seguro vacío puesto que ya no nos hace falta. Lo hemos quitado por fin ya que ahora loa vamos a usar al crear un nuevo seguro médico.
- Línea 21: Llamamos al servidor para que actualice los datos del seguro médico en la base de datos del servidor.
- Línea 22: En caso de que se hayan actualizado los datos , navegamos a la página del listado de seguros médicos usando el servicio
$location.
Añadir un nuevo seguro médico
Para añadir un nuevo seguro es necesario añadir una nueva ruta y crear un nuevo controlador.
El path de la nueva ruta será /seguro/new y el controlador se llamará NewSeguroController. Añadiremos el siguiente código debajo de las rutas que habíamos definido en el bloque de configuración:
$routeProvider.when('/seguro/new', {
templateUrl: "detalle.html",
controller: "NewSeguroController"
});
- Línea 2: Hay que destacar que estamos usando la misma página HTML que para la edición. No hay ningún problema en reutilizar una misma página en dos rutas distintas o también reutilizar incluso el controlador.
El controlador quedará de la siguiente forma:
app.controller("NewSeguroController", ['$scope', 'remoteResource', '$location', function($scope, remoteResource, $location) {
$scope.filtro = {
ape1: ""
};
$scope.sexos = [{
codSexo: "H",
descripcion: "Hombre"
}, {
codSexo: "M",
descripcion: "Mujer"
}];
$scope.seguro = {
nif: "",
nombre: "",
ape1: "",
edad: undefined,
sexo: "",
casado: false,
numHijos: undefined,
embarazada: false,
coberturas: {
oftalmologia: false,
dental: false,
fecundacionInVitro: false
},
enfermedades: {
corazon: false,
estomacal: false,
rinyones: false,
alergia: false,
nombreAlergia: ""
},
fechaCreacion: new Date()
};
$scope.guardar = function() {
if ($scope.form.$valid) {
remoteResource.insert($scope.seguro).then(function() {
$location.path("/seguro/listado");
}, function(bussinessMessages) {
$scope.bussinessMessages = bussinessMessages;
});
} else {
alert("Hay datos inválidos");
}
};
}]);
Para acceder a esta nueva página 1) añadimos un en la en la página del listado de seguros médicos
<a href="#/seguro/new">Nuevo Seguro Medico</a>
