I'm writing applications with Java backend and frontend in AngularJS. My problem is that I can not get data in JavaScript Controller. Although Java server sends the data correctly.
Java - Service:
#GET
#Path("/get/list/{id}")
#Produces("application/json")
public List<Room> getList(#PathParam("id") int id) {
List<Room> list = service.getList(id);
return list;
}
JavaScript - Service:
app.factory("BuildingService", function($resource, $q) {
var BuildingService,
Rooms = $resource("/api/rest/room/get/list/:id", {
id: "#id"
});
BuildingService = {
getListRooms: function(id) {
return Rooms.get({id: id}).$promise;
}
};
return BuildingService;
});
JavaScript - Controller:
app.controller("BuildingController", function($scope, $routeParams, BuildingService) {
BuildingService.getListRooms($routeParams.id).then(function(list) {
$scope.rooms = list;
}, function(err) {
console.error(err);
});
});
error in console:
Error: [$resource:badcfg] http://errors.angularjs.org/1.2.14/$resource/badcfg?p0=object&p1=array
I do not understand this error.
Please help
Regards,
You are returning from backend side List i.e. collection of rooms , so you should use query method of angular js instead of get. In your BuildingRoomService change get to query
The link that the angular error tells you what the problem is
"To resolve this error, make sure your $resource configuration matches
the actual format of the data returned from the server."
the $resource call is expecting a json array response but apparently receives an object. Check to see what is actually returned by the server, the actual json response.
Your issue may be related to this other issue: Spring 3 ArrayList serialization to JSON with Jackson without wrapping to object (without name)
Related
I am attempting an application in JHipster 7.0.1 (Azul JDK 11) and ReactJS as the front-end.
I have 2 entities in my JDL - Domain and BadgeCategory that are related as shown below
relationship OneToMany {
Domain{badgeClass required} to BadgeCategory{domain(name) required}
I want to be able to display all the BadgeCategories for a particular Domain in the Domain Detail screen.
For this, I created a new method in the repository BadgeCategoryRepository.java
#Repository
public interface BadgeCategoryRepository extends JpaRepository<BadgeCategory, Long> {
List<BadgeCategory> findByDomainId(Long id);
}
And then added a new endpoint in BadgeCategoryResource.java
#GetMapping("/badge-categories-domain/{id}")
public ResponseEntity<List<BadgeCategory>> getAllBadgeCategoriesForDomain(#PathVariable Long id) {
log.debug("REST request to get BadgeCategories for Domain : {}", id);
List<BadgeCategory> badgeCategory = badgeCategoryRepository.findByDomainId(id);
return ResponseEntity.ok().body(badgeCategory);
}
Now coming to the React part, I added a constant in badge-category.reducer.ts
export const getEntitiesForDomain = createAsyncThunk(
'badgeCategory/fetch_entity_list_for_domain',
async (id: string) => {
const requestUrl = `api/badge-categories-domain/${id}`;
alert(JSON.stringify(axios.get<IBadgeCategory[]>(requestUrl)));
return axios.get<IBadgeCategory[]>(requestUrl);
});
Then I am using this reducer in the Domain Detail screen component domain-detail.tsx
import { getEntity as getBadgeCategory, getEntitiesForDomain } from '../badge-category/badge-category.reducer';
const domainEntity = useAppSelector(state => state.domain.entity);
const badgeCategoryList = useAppSelector(state => state.badgeCategory.entities);
useEffect(() => {
dispatch(getEntity(props.match.params.id));
dispatch(getEntitiesForDomain(props.match.params.id));
}, []);
I am expecting the constant badgeCategoryList to contain the list of all badge categories for the domain which is being referred to in the domain-detail screen. But I get nothing in return.
On checking the flow, I see that the endpoint is getting hit and the response is being produced by the Java code, but the UI code is not able to consume it.
What am I missing here that is causing this issue?
The Swagger docs show expected response from the Java code
So the issue was with the new API call not being registered with the slice section in the reducer. I had to do the following addition to the slice and it works like a charm
.addMatcher(isFulfilled(getEntitiesForDomain), (state, action) => {
return {
...state,
loading: false,
entities: action.payload.data,
};
})
I'm trying to create an api to delete a certain ID from the storage;
Here's my code.
API Controller:
#DeleteMapping("{cId}")
#ResponseStatus(HttpStatus.OK)
public String delete(#PathVariable String cId) {
compareService.delete(cId);
return "redirect:/compare";
}
Service:
public void delete(String cId) {
compareLogic.delete(cId);
}
Logic:
public void delete(String cId){
System.out.println("A: " + sessionModel.getCIds());
List<String> update = sessionModel.getCIds();
update.remove(new String(cId));
System.out.println("B: " + sessionModel.getCIds());
}
However when I execute the api it shows
{
success: false,
warning: false,
error: "405",
error_description: "Method Not Allowed"
}
Are there any possible reasons by just looking at the code?
Many thanks,
Just I have tired with simple code snippet , Could you please try to understand and (Try to follow my suggestion as well )
When you hit from browser side (From Address Bar), it won't work for POST/PUT/DELETE calls , it is actually working from browser, if you try to typing in address bar then it is a GET request then it will not supported to the other format
Just I have added two screenshot I have tired with Browser and PostMan
First I have tired with POSTMAN (it is working perfectly)
Second I have tired with Browser (It will throw not supported
exception )
I have tired with small code snippet just copy from your code and remove element from list
#DeleteMapping("{cId}")
public String delete(#PathVariable String cId) {
List<String> arr=new ArrayList<String>(3);
arr.add("A");
arr.add("B");
arr.add("C");
arr.remove(cId);
for (String string : arr) {
System.out.println(string);
}
return "redirect:/compare";
}
The reason for this error is sending the request with a non-supported method. 405 Status Code indicates that the server doesn't support the method or verb sent in the request.
Could you also provide the API call details like HTTP method and relative path ? recheck your API details, make sure you are using correct HTTP method.
I get a list of object from server. One key of this objects is called body, and it is a json. It is almost impossible for me to know its keys : the key name and size of it (body) are different.
Example of data
data from server = [object, object, object,.....]
object = {
id: 1,
name: "xyz",
body": {
x: "xyz",
y: "xyz",
z: "xys",
}
}
I edit the body and then post it to the server together with the id of the object. Until here it is fine. I can send the request but can not handle the Requestparam which is of type json.
How to handle this post request on the backend built in Java and Spring?
You have to add a #RequestBody annotation to the method on the Controller such as:
#RequestMapping ("url/to/save")
#ResponseBody
public ResponseObject send (#RequestBody RequestObject myRequestObject)
{
//do something
return new ResponseObject ();
}
The RequestObject would be the Java Class mapping to the JSON you want to save. The ResponseObject is whatever you want to return, you could also return void but Firefox has issues with that sometimes.
I have a simple REST client with GET POST and DELETE methods.
Weird things is that only GET methods work, neither POST nor DELETE doesn't even get hit and response is "404 Not Found" of course.
Here's my REST service and the client:
Interface:
public interface MyInterface {
#GET
#Path("/content")
#Produces(MediaType.APPLICATION_JSON)
Response getAirports();
#DELETE
#Path("/content/{id}")
#Produces(MediaType.APPLICATION_JSON)
Response deleteAirport(#PathParam("id") String id);
}
Implementation:
#Path("/source")
public class SourceService extends AbstractService implements MyInterface {
#Override
public Response getContent() {
DBCollection collection = getDBCollection("content");
DBCursor cursor = collection.find();
String serialize = JSON.serialize(cursor);
return Response.status(Response.Status.OK).entity(serialize).build();
}
#Override
public Response deleteContent(#PathParam("id") Integer id) {
DBCollection collection = getDBCollection("content");
BasicDBObject query = new BasicDBObject();
query.append("id", id);
collection.remove(query);
return Response.status(Response.Status.OK).build();
}
}
Client:
// This is working
public void getContent() {
WebTarget path = collect.path("/content");
Response response = path.request().get();
LOGGER.info("collect.ping: " + response.readEntity(String.class) + "\n");
}
// This is not working
public void deleteContent(Integer id) {
WebTarget path = collect.path("/content/"+id);
Response response = path.request(MediaType.APPLICATION_JSON).delete();
System.out.println("object deleted:"+response);
}
I've tried requesting with jersey or apache clients but all of them return 404 and I'm like hopeless now.
Hope you can give me a direction.
This looks like a possible duplicate of Inheritance with JAX-RS. Have you tried replicating all annotations in the subclass or none, means do not use #PathParam in the implementation class at all?
If you actually can debug your client and you are indeed able to "Step through" the client code?
If you place a break-point within your server code and you never actually "break" on it? Then the problem is with the way you are exposing your web service and how you are then trying to consume it.
Try to change the parameter type expected by the Server and the type you pass from your client.
If you can change it on the server and client to a simpler type.. i.e.. an integer.. and then you can actually capture a breakpoint in both client and server, then you know that the problem is in your types.
I hope you can understand what I'm saying? You really need to simplify your parameters and/or try it without parameters first.
When you get something simpler working, then you can extend it to something else.
try just changing it to a string... such as "airport" Also, you are passing a parameter in the client as this:
public void deleteAirport(String iata) {
But you don't use "iata" in your client code...
I was developing a restful web client and trying to get the JSON payload from the response of a GET method. I am using Jersey. But I just cannot read the JSON data using response.getEntity() method. I tried many methods including response.bufferEntity(), but the output always kept empty. Below is my code and output, and in addition I can see the JSON data right in the response packet captured in wireshark. I would really appreciate everyone trying to help figure out why or provide solution. Thank you!
Code:
public JSONObject Get(String requestPath){
ClientResponse response = webResource.path(requestPath)
.header("Content-Type", contTypeHeader )
.header("Accept",acceptHeader)
.header("Authorization", authZ )
.get(ClientResponse.class);
response.bufferEntity();
if (!(response.getStatus() == 201 || response.getStatus() == 200)) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
System.out.println(response.getEntity(JSONObject.class));
return null;
}
and the output is always like this: {}
You can't use JSONObject unless you have a MessageBodyReader for it. See more at JAX-RS Entity Providers. The provider you are currently using (probably Jackson) only supports JavaBean POJOs or collections of them. For example if you have this JSON
{ "property1" : "value1", "property2": "value2" }
Then you would need to have a POJO like
public class Bean {
private String property1;
private String property2;
// getters and setters
}
Then you can do getEntity(Bean.class). The reason you are getting an empty object, is that the deserialization works off the setters. It looks for properties on the JSON, that matches a setters, and uses it the set the property. The JSON object has no setters for your JSON properties.