Return response from AngularJS factory - java

I am trying to return a response from server.
Take the example of adding a car to the server, my AngularJS factory is the following:
app.factory('CarServices', function ($resource) {
return $resource('/ws/cars', {}, {
query: { method: 'GET', isArray: true },
create: { method: 'POST' },
delete: { method: 'DELETE', params: {id: '#id'} }
})
});
Then, In my CarController I have this function:
// callback for ng-click 'addCar':
$scope.addCar= function () {
$scope.car = { "plate": "778899", "brand": "Ferrari" };
CarServices.create($scope.car).$promise.then(function() {
// If success, show success message
}, function(error) {
// If error, show message from server
});
}
I am using Java with RESTful WebServices and this is my WebService:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response addCar(JsonCar jc) {
Car car = new Car(jc.getPlate(), jc.getBrand());
if(car.getByPlate()) {
return Response.ok().build();
} else {
return Response.status(Response.Status.NOT_ACCEPTABLE)
.entity("Car does not exist on database").build();
}
}
So, I wan't that in case of error on the controller, show the message "Car does not exist on database" but instead of that I am getting this error (console.log(error)):
json.parse unexpected end of data at line 1 column 1 of the json data
Thank you.

Related

React "fetch" method not talking to java based Controller

I am attempting to get some data from a database to load into a React based component in my front end. In order to do this, I have created a fetch request that talks to a java based controller on the backend that then eventually hits the database and pulls the information from the database. However, when I attempt to maven build the project, it fails repeatedly and provides the error "TypeError: Cannot read property 'then' of undefined" which from searching implies a Promise isn't being returned by the fetch request.
My assumption based on several tests is that my fetch request isn't actually being directed to my controller somehow (and debugging the build fails to hit a breakpoint within the controller as well). Looking for any assistance to see why these two pieces aren't talking to each other.
I should also mention I have an insert method in the same view portion that talks to the same controller and that works successfully.
Controller Portion:
#Component
#RestController
#RequestMapping(value="/api/process/")
public class ProcessController {
private final ProcessService processService;
#Autowired
public ProcessController(ProcessService processService) { this.processService = processService; }
#RequestMapping(value="add", method = RequestMethod.POST)
public ResponseEntity<String> insertProcess(#RequestBody() String processJson) {
Gson gson = new Gson();
Process process = gson.fromJson(processJson, Process.class);
try {
return new ResponseEntity<>(gson.toJson(processService.insertProcess(process)), HttpStatus.OK);
} catch(DataAccessException de) {
return new ResponseEntity<>(de.getCause().getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
#RequestMapping(value="select", method = RequestMethod.POST)
public ResponseEntity<String> selectProcesses() {
try {
return new ResponseEntity<>(new Gson().toJson(processService.selectProcesses()), HttpStatus.OK);
} catch(DataAccessException de) {
return new ResponseEntity<>(de.getCause().getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
And the fetch calls:
class ProcessApi {
static addProcess(processJson) {
return fetch('/api/process/add', {
method: 'POST',
body: processJson
})
.then(response => {
if(response.status === 200) {
return response.json()
.then(jsonData => {
return jsonData;
});
}
})
.catch((error) => {
console.error(error);
return error.json();
});
};
static getProcesses() {
return fetch('/api/process/select', {
method: 'POST'
})
.then(response => {
if(response.status === 200) {
return response.json()
.then(jsonData => {
return jsonData;
});
}
})
.catch((error) => {
console.error(error);
return error.json();
});
};
}
As mentioned, the "addProcess" portion works just fine. The select just isn't connecting up and I can't seem to find out why. For reference I have the API call happening in the componentDidMount() method in my view portion.

Rest DELETE Bad Request

Can u explain me why DELETE method (store.remove() in Edit.js) throws 400 Bad request. Other method works well. In header request url seems to be ok "http://localhost:8080/Diary/rest/notes/22?_dc=1461837327580".
I know that problem is in payload of DELETE method, store.remove() includes ID as payload. How can i disable that and send DELETE method without body, because ID is already in URL
Rest Service
#Path("/notes")
public class NoteRestService {
#Context
private UriInfo uriInfo;
#Context
private HttpServletRequest request;
private NoteDaoImpl noteDao = new NoteDaoImpl();
#GET
#Produces("application/json")
public String getNotes(){
String login = request.getSession(true).getAttribute("login").toString();
List<Note> notes = noteDao.getUserNotes(login);
return new Gson().toJson(notes);
}
#POST
#Consumes("application/json")
public Response postNote(Note note){
String login = request.getSession(true).getAttribute("login").toString();
note.setUser(login);
noteDao.persist(note);
URI noteUri = uriInfo.getAbsolutePathBuilder().path(Long.toString(note.getId())).build();
return Response.created(noteUri).build();
}
#PUT
#Path("{id}")
#Consumes("application/json")
public Response updateNote(#PathParam("id") String id,Note note){
String login = request.getSession(true).getAttribute("login").toString();
Note editNote = noteDao.getNote(Long.parseLong(id));
note.setCreated(editNote.getCreated());
note.setUser(login);
noteDao.update(note);
return Response.ok().build();
}
#DELETE
#Path("{id}")
public Response deleteNote(#PathParam("id") String id){
Note note = noteDao.getNote(Long.valueOf(id));
if (note==null){
throw new NotFoundException();
}
noteDao.delete(Long.parseLong(id));
return Response.noContent().build();
}
}
EditController.js
Ext.define('MVC.controller.Edit', {
extend: 'Ext.app.Controller',
init: function () {
this.control({
'editForm > button#SaveRecord': {
click: this.onSaveButtonClick
},
'editForm > button#DeleteButton': {
click: this.onDeleteButtonClick
}
});
},
onSaveButtonClick: function (btn) {
//get reference to the form
var detailView = btn.up('editForm');
//get the form inputs
var data = detailView.getValues();
//see if the record exists
var store = Ext.getStore('TestStore');
console.log(data.id);
var record = store.getById(data.id);
if (!record) {
record = Ext.create('MVC.model.Note', {
title: data.title,
created: new Date(),
updated: new Date(),
text: data.text
});
Ext.MessageBox.alert('Created', data.title);
store.insert(0, record);
store.sync();
return;
}
record.set(data);
store.sync();
//manually update the record
detailView.updateRecord();
},
onDeleteButtonClick: function (btn) {
//get reference to the form
var detailView = btn.up('editForm');
//get the form inputs
var data = detailView.getValues();
var store = Ext.getStore('TestStore');
var record = store.getById(data.id);
store.remove(record);
store.sync();
}
});
UPD: Store
Ext.define('MVC.store.TestStore', {
extend: 'Ext.data.Store',
requires: [
'MVC.model.Note'
],
storeId: 'TestStore',
model: 'MVC.model.Note',
autoLoad: false,
proxy: {
type: 'rest',
url: 'rest/notes',
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy:' DELETE'
},
reader: {
type: 'json',
rootProperty: 'data'
},
writer: {
type: 'json',
writeAllFields: true
}
}
});
You can't have a HttpMethod.DELETE with a body.
This is not explicitly stated in the RFC, but some Proxy servers will reject the body if you have one in a delete method. Spring lowers the standard and will reject your query with a Bad Request.
Remove the body as well as the answer to fix your issue.
Check this for more information:
Is an entity body allowed for an HTTP DELETE request?
If TestStore is the store you're using, I'd guess that your problem is here:
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'GET'
},
I don't recognize the #DELETE annotation, so I'm not 100% sure but if your controller is expecting DELETE, and you're sending GET, that could explain the 400 error.

Error 405 Method Not Allowed error, when sending DELETE to server

I get following response when I try to delete: 405 Method Not Allowed.
In my logs there is written that GET is allowed, but DELETE isn't.
Java:
#ResponseBody
#RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void delete(#PathVariable String id) {
speakerService.delete(id);
}
Angularjs
app.factory('SpeakerResource', function ($resource) {
return $resource('rest/speaker/:speakerId',
{
speakerId: '#speakerId'
},
{
'update': { method: 'PUT' }
},
{
'delete': { method: 'DELETE', params: { 'id': 'speakerId' }}
}
)
});
SpeakerService
this.delete = function (id, callback) {
SpeakerResource.delete({ speakerId: id }, function () {
callback();
});
}
I do not know your complete code, and I am not an expert in AngularJS, but it looks like your want to send a DELETE request to the URL <hopefullySomething>/{id} (Path variable). But it looks like that you send a DELETE request so some URL with an parameter id <hopefullySomething>?id={id} (Request parameter).
This question and answers explain the difference between path variable and request parameters a bit more #RequestParam vs #PathVariable
use $http.delete(), and return data for example status, I just tested the following with spring and working correctly
#RequestMapping(value = "delete/{id}", method = RequestMethod.DELETE)
public #ResponseBody Status deletePerson(#PathVariable("id") int id) {
try {
personService.removePerson(id);
return new Status(1, "person deleted Successfully !");
} catch (Exception e) {
return new Status(0, e.toString());
}
}
angular
angular.module('personService', [])
.factory('Person', ['$http',function($http) {
return {
deletePerson: function(id) {
return $http.delete('/restperson/delete/'+id);
}
}
}]);
controller
angular.module('personController', [])
// inject the person service factory into our controller
.controller('mainController', ['$scope','$http','Person', function($scope, $http, Person) {
//delete
$scope.deletePerson = function(id) {
Person.deletePerson(id)
.success(function(data) {
$scope.message = data;
});
};
}]);

How to receive the input parameters in REST Service call?

I am performing an AJAX request this way
$.ajax({
type: 'GET',
url: 'http://hosti[:8080/OrderSnacks/oms/toppings?topping=' + id_attr_val,
jsonpCallback: 'jsonCallback',
cache: true,
dataType: 'jsonp',
jsonp: false,
success: function (response) {
console.log(response);
},
error: function (e) {
$("#divResult").html("WebSerivce unreachable");
}
});
});
Inside my REST service call , i am unable to receive this parameter
#Path("/toppings")
public class ToppingService {
#GET
#Consumes("application/text")
#Produces("application/json")
public String getData(#PathParam("toppingid") String toppingid) {
return "";
}
I have tried all the options that is
public String getData(#QueryParam("toppingid") String toppingid) {
}
public String getData(#PathParam("toppingid") String toppingid) {
}
But nothing is working .
Could you please tell me how to receive those parameters ??
You have a problem : you send topping but you ask for toppingid.

response status from server to client

In my app I want to respond from server to client the status of the operation, for example, from client sends data in format json to server and I want that this responds whit status of the operation, if these data have inserted correctly in database to send status 200,...
I now have this.
Client:
function sendAjax() {
//I build the params necessary to send to server in format json
$.ajax({
url: "/url",
type: 'POST',
dataType: 'json',
data: param,
contentType: 'application/json',
mimeType: 'application/json',
success: function(data) {
alert(data.id );
},
error: function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
});
alert();
}
Server:
Controller.java
#RequestMapping(value = "/", method = RequestMethod.POST)
public #ResponseBody
ResponseJson post (#RequestBody String string){
//I have the operations necessary to insert in database
ResponseJson pruebaJson = new ResponseJson ();
pruebaJson.setId (id);
return pruebaJson;
}
ResponseJson.java
public class ResponseJson implements Serializable
{
private String id;
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
}
How will I process the status that server send to client? this is, if I get status 200 or other status.
My app is realized in spring-mvc and I use javascript with ajax to send data in format json from client to server.
Thanks
You can do it by :
$.ajax({
statusCode: {
404: function() {
alert( "page not found" );
},
200: function() {
alert("insert done..!!!");
},
}
});
This may help you.
See JQuery API for more option.
EDIT : on the basis of my understanding you want to check status code inside success or error function for that
success: function(data , textStatus, jqXHR) {
alert(data.id );
var statusCode = jqXHR.status
if(statusCode == 200 ){
//Your code execute if status is 200
}
}
like wise you can do it in error function also.
In your ajax call success function executes when server sends status 200 code. other than that your error function only executes.
If you want to handle error status separately you can handle in error function with return status.

Categories