I'm using Angular and ES6 to send data to Spring Boot RESTful API.
class PostsService {
constructor($http) {
this.getAllPosts = () => {
return $http.get('http://localhost:8080/posts');
};
this.addPost = () => {
let data = {content : "BBB", date : "55.55.5555"};
return $http.post('http://localhost:8080/newPost', data);
};
}
}
PostsService.$inject = ['$http'];
export default angular
.module('blog.Posts')
.service('PostsService', PostsService);
GET request works without any problems.
POST totally sends the data (REST API gets it and puts it into the database as it should), on the other hand, generates this silly, and completely weird error:
SyntaxError: Unexpected token O
at Object.parse (native)
at fromJson (http://localhost:4000/build/bundle.js:1351:15)
at defaultHttpResponseTransform (http://localhost:4000/build/bundle.js:10202:17)
at http://localhost:4000/build/bundle.js:10293:13
at forEach (http://localhost:4000/build/bundle.js:390:21)
at transformData (http://localhost:4000/build/bundle.js:10292:4)
at transformResponse (http://localhost:4000/build/bundle.js:11065:22)
at processQueue (http://localhost:4000/build/bundle.js:15621:29)
at http://localhost:4000/build/bundle.js:15637:28
at Scope.$eval (http://localhost:4000/build/bundle.js:16889:29)
I think it's worth to point out, that I'm using webpack, and no JSON parsing is done whatsoever (excluding angular http parsing, that I have no information of).
The thing was - it is somehow required, that backend returns JSON. So I changed:
#RequestMapping(path="/newPost", method= RequestMethod.POST)
public #ResponseBody() String createPost(#RequestBody Post payload) {
repository.save(payload);
return "OK";
}
to:
#RequestMapping(path="/newPost", method= RequestMethod.POST)
public #ResponseBody() List<String> createPost(#RequestBody Post payload) {
repository.save(payload);
List<String> list = new ArrayList<String>();
list.add("OK");
return list;
}
And it worked. Cheers doods!
Related
I try to send data to my NodeJS server using HTTP protocol (vue-resource). I want to send a array of JSON object like this : [{"name":"Charlotte","surname":"Chacha","birth":"2000-04-02"},{"name":"Michael","surname":"Mic","birth":"1999-01-30"}].
My front code :
window.onload = function () {
var gamme = new Vue({
el:'#gamme',
data: {
myListe: []
},
methods: {
sendListe: function() {
this.$http.get("/NewListe?liste="+this.myListe).then(response=> {
if (response.body) {
console.log(response.body);
}
});
}
}
})
}
And my back code :
server.app.get("/NewListe", function(req, res) {
try {
let liste= req.query.liste;
console.log(liste);
} catch (e) {
console.log(e);
}
})
When I try to display the variable liste in the server side console, I obtain this : [object Object] . liste is a string type that I can't use. I would like to have an array of JSON, like in front.
I tried to parse like this JSON.parse(operationsGamme) , but I have this error : SyntaxError: Unexpected token o in JSON at position 1
You should surely be using a POST method if you are sending JSON data to the server - a GET just isn't designed for that sort of usage.
Since you have passed a JSON in the url, it will be URLEncoded. So, in the backend before you do JSON.parse(liste), you should do decodeURI(liste). decodeURI() will return the JSON string which you can parse and use it in your code. I hope this will fix your problem.
I'm trying to insert into a FormData an array of arrays and a string, however java seems to not receive it , I have no log error in my Java server however I have a 500 Internal Server Error in my JavaScript console.
Here is the code for my controller :
#RequestMapping(value = "/getReporting", method = RequestMethod.POST)
#ResponseBody
public void getReporting(#RequestParam RecommendationForm form, #RequestParam String type, HttpServletResponse response) throws ApcException {
System.out.println("prova");
Map.Entry<String, byte[]> result = this.reportingService.getReporting(form,type);
try {
response.setHeader(//
"Content-Disposition",//
"attachment; filename=" +"bobo.xlsx");
response.setContentType("Application/x");
response.getOutputStream().write(result.getValue());
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And here is my service in Angular :
public getExcel(form: FormData): Observable<HttpResponse<Blob>> {
return this.http.post('/SV-AUD/api/reporting/getReporting', form, {observe: 'response', responseType: 'blob'});
}
And the component where I append the info in the formData :
form: FormGroup = this._fb.group(
{
hello1: [],
hello2: [],
hello3: [],
hello4: [],
hello5: [],
hello6: [],
hello7: [],
hello8: [],
hello9: [],
}
);
exportExcel() {
const formData: FormData = new FormData();
formData.append('form', this.form.getRawValue());
if (this.detailedType) {
formData.append('type', 'detailed');
} else {
formData.append('type', 'list');
}
this.reportingService.getExcel(formData).subscribe(data => {
const ctHeader = data.headers.get('content-disposition');
if (ctHeader) {
const filename = ctHeader.split('=')[1];
saveAs(data.body, filename);
}
});
}
The behavior that you are describing suggests that Spring is unable to bind your #RequestParam parameters of your getReporting method to the incoming request.
That means that the data that you are posting from the Angular side does not match up with what is expected on the Spring side.
Unless it's a typo, I'm guessing that the problem is this line in your component's source code, which does nothing (and should be a syntax error due to mis-matched parens):
(this.form.getRawValue()));
I'm guessing that it should be :
formData.append('form', (this.form.getRawValue()));
Angular/JavaScript amateur here, working on my first project using this framework. I have a Component that uses a Service which performs a GET request to a given URL.
Component:
#Component({
selector: 'jive-list',
templateUrl: './jivelist.component.html',
styleUrls: ['./jivelist.component.css']
})
export class JiveListComponent implements OnInit {
JiveLists: String[]; //placeholder
constructor(private JiveListService: JiveListService) { }
getJiveList(): void {
console.log("test");
this.JiveListService.getData().subscribe(
data => console.log(JSON.stringify(data)));
}
ngOnInit() {
this.getJiveList();
//console.log(this.JiveLists) //placeholder
}
}
Service:
#Injectable()
export class JiveListService {
API_URL = environment.JIVEAPIURL //can append endpoints where needed
constructor (public http: HttpClient) {
console.log("constructor runs");
}
getData(): Observable<any> {
return this.http.get<any>(this.API_URL).map((res) => res);
}
}
The API URL is a local file for now, located at './assets/data/data.json'
This code essentially gets a JSON from the URL and logs it in the console. When the file is purely JSON, this works with no issues. However, the JSON that will be provided in production always starts with a string.
JSON sample:
throw 'allowIllegalResourceCall is false.';
{
"id" : "123456",
"resources" : {
//rest of the JSON
I have tried the two solutions recommended in this article, but none of them have changed my result.
Example (attempted) solution:
getData(): Observable<any> {
return this.http.get<any>(this.API_URL).map((res) => res.substring(res.indexOf('{')));
}
My error message:
SyntaxError: Unexpected token h in JSON at position 1 at Object.parse (<anonymous>) at XMLHttpRequest.onLoad (http://localhost:4200/vendor.bundle.js:43048:37) at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:2513:31) at Object.onInvokeTask (http://localhost:4200/vendor.bundle.js:75481:33) at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:2512:36) at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (http://localhost:4200/polyfills.bundle.js:2280:47) at ZoneTask.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:4200/polyfills.bundle.js:2587:34) at invokeTask (http://localhost:4200/polyfills.bundle.js:3628:14) at XMLHttpRequest.globalZoneAwareCallback (http://localhost:4200/polyfills.bundle.js:3654:17)
Any ideas that would help me fix this issue would be appreciated. I am using Angular 4.2.4, and using #Angular/common/HttpClientModule as my HTTP handler.
Could you try this instead then,
the getData() method in service,
getData(): Observable<any> {
return this.http.get<any>(this.API_URL);
}
the getJiveList() in component,
getJiveList(): void {
console.log("test");
this.JiveListService.getData()
.subscribe(data => {
data = data.toString().substring(data.toString().indexOf('{'));
console.log(data);
});
}
If this doesn't work, then may be it is likely due to way we parse the data from the GET request.
The issue was found to come from the HttpClientModule's get method, which will automatically run json.parse() on the response if it is requesting a URL ending in .json. I was unable to find a simple fix for this on the front-end, instead I referred to a Spring API which would redirect my request and use a modified JSON-parsing method that trims the string from the file.
I am following up in the course AngularJS Front to Back with Web API using ASP.net, we are trying to do queries using ODATA so i added this code in the ProductController in the WebAPI
// GET: api/Products
[EnableQuery()]
public IQueryable<Product> Get()
{
var productRepository = new ProductRepository();
return productRepository.Retrieve().AsQueryable();
}
then added the below code in the productcontroller in the angular code:
function ProductListCtrl(productResource) {
var vm = this;
productResource.query({$skip:1, $top:3}, function (data) {
vm.products = data;
})
but when I try to run it gives me the below error:
angular.js:12701 GET http://localhost:59302//api/products?$skip=1&$top=3 400 (Bad Request)
Possibly unhandled rejection: {"data":{"message":"The query specified in the URI is not valid. No non-OData HTTP route registered.","exceptionMessage":"No non-OData HTTP route registered.",.....
Maybe you don't have odataConfiguration?? Where's you EDM configuration?
In your config file you need something like that:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// New code:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
}
}
I'm making a simple establishment of registration that must have data and a logo. In tests could transmit the file and the data separately but when trying to send them together the following error occurs:
SyntaxError: Unexpected token S
at Object.parse (native)
at qc (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:14:245)
at Zb (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:76:423)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:77:283
at r (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:7:302)
at Zc (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:77:265)
at c (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:78:414)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:112:113
at n.$get.n.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:126:15)
at n.$get.n.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:123:106)
The Angular Controller
angular.module('EntregaJaApp').controller('EstabelecimentoController', ['$scope', '$http','Upload', function($scope, $http,Upload){
$scope.salvar = function(){
Upload.upload({
url: 'http://localhost:8080/site-web/gerencial/estabelecimento/salvar',
file: $scope.picFile[0],
method: 'POST',
headers: {'Content-Type': 'multipart/form-data'}, // only for html5
data: {'estabelecimento': $scope.estabelecimento}
});
}}
The Spring Controller
#Controller
#RequestMapping("/gerencial/estabelecimento")
public class EstabelecimentoController {
#Autowired
private EstabelecimentoService estabelecimentoService;
#RequestMapping(value = "/salvar", method = RequestMethod.POST)
public ResponseEntity<?> salvar(Estabelecimento estabelecimento,#RequestParam(value="file", required=false) MultipartFile file){
try {
byte[] bytes;
if (!file.isEmpty()) {
bytes = file.getBytes();
//store file in storage
}
System.out.println(String.format("receive %s from %s", file.getOriginalFilename(), estabelecimento.getNome()));
estabelecimentoService.salvar(estabelecimento);
return new ResponseEntity<>(MensagensGerais.SUCESSO_SALVAR,HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>((StringUtil.eVazia(e.getMessage()) ? MensagensGerais.ERRO_CONSULTAR : e.getMessage()),HttpStatus.BAD_REQUEST);
}
}
}
did you missed the return type annotation? Like
#RequestMapping(value = "/salvar", method = RequestMethod.POST)
#Produces(MediaType.APPLICATION_JSON)
public ResponseEntity<?> salvar(Estabelecimento estabelecimento,#RequestParam(value="file", required=false) MultipartFile file){...}
Assuming that the request specifies an Accept Header "application/json", it seems that the Strings are not correctly serialized (by Spring?). Angular versions prior to 1.3.x seem to have been generous, but now an exception is thrown when the response is not correct JSON. I have added the following response transformer to my app:
$httpProvider.defaults.transformResponse.unshift(function(data, headersGetter, status){
var contentType = headersGetter('Content-Type');
if(angular.isString(contentType) && contentType.startsWith('application/json')){
try {
angular.fromJson(data);
} catch(e){
var mod = '"'+data+'"';
try {
angular.fromJson(mod);
return mod;
}
catch(e){
return data;
}
}
return data;
}
else{
return data;
}
});
It transforms a JS string to a JSON string object by wrapping it in additional ".