Unexpected token in JSON at position 0 - Angular2 - Spring API - json

My REST API which has been written in SpringBoot has following method for the purpose of uploading a photo.
#RequestMapping(method = RequestMethod.POST, value = "/save-photo")
public ResponseEntity<?> uploadPhoto(#RequestPart("file") MultipartFile file){
if (file.isEmpty()) {
System.out.println("Attached file is empty");
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage("Attached file is empty");
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
String returnPath = null;
try {
byte[] bytes = file.getBytes();
String saveDate = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date());
Path path = Paths.get(UPLOAD_FOLDER + saveDate + "___" + file.getOriginalFilename());
Files.write(path, bytes);
returnPath = String.valueOf(path);
} catch (IOException e) {
//e.printStackTrace();
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage(e.getMessage());
return new ResponseEntity<ErrorResponse> (errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
System.out.println("Before returning, return path = "+returnPath);
return new ResponseEntity<String>(returnPath, HttpStatus.OK);
}
Following is the code I have written to call the above method.
savePhoto(photoToSave: File) {
let formData: FormData = new FormData();
formData.append("file", photoToSave);
let savedPath = this._http
.post(this._endpointUrl + "/save-photo", formData)
.map(
res => {
return res.json();
}
)
.catch(handleError);
return savedPath;
}
File uploading process is fine. But Angular2 gives me the following error.
Unexpected token F in JSON at position 0
Note that the F is the starting letter of the path the server returns.
Why this happens? I think the server response is not a JSON. But why? Usually RestControllers return JSON. All other controller methods in my server works fine.
How to resolve this?
Response Captured from Browser console
Header:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:3000
Content-Length:88
Content-Type:application/json;charset=UTF-8
Date:Fri, 26 May 2017 04:33:05 GMT
Vary:Origin
Response:
F:\Work\Images\170526100305388___2.jpg
EDIT
Screen shots from the brwoser
Response:

Posting as a answer the workaround I used to get over the issue. Hope it might help somebody.
What I did was instead of returning a String ResponseEntity, I created a JSON object which encapsulates the string I want to return and returned as the response.
JSONObject obj = new JSONObject();
obj.put("savedPath", returnPath);
return new ResponseEntity<>(obj, HttpStatus.OK);
In the front end, I just return the response.json()
let savedPath = this._http
.post(this._endpointUrl + "tender/save-new/save-photo", formData)
.map(
res => {
return res.json();
}
)
.catch(handleError);
Now in the controller class, I can access the saved path in following way.
this._tendersService.savePhoto(files[0])
.subscribe(res => {
console.log("saved path = " + res.savedPath);
}
);

Related

Flutter/Dart Error - NoSuchMethodError (NoSuchMethodError: Class 'String' has no instance method 'map'

I receive an error that has something to do with JSON receiver inside Flutter/Dart.
Had to share in a docs file since the full json response is pretty long. It had like 15 columns error log
Detail Class
class Detail {
String kodkursus;
String namakursus;
String kursusdescription;
Detail(
{required this.kodkursus,
required this.namakursus,
required this.kursusdescription});
factory Detail.fromJson(Map<String, dynamic> json) {
return Detail(
kodkursus: json['crs_code'] as String,
namakursus: json['crs_title_bm'] as String,
kursusdescription: json['crs_description_bm'] as String,
);
}
}
Code
Future<dynamic> generateDetailList() async {
var url = 'http://10.0.2.2:81/login_testing/kursus_display.php';
var data = {'usr_id': widget.username2};
var response = await http.post(url, body: json.encode(data));
var list = json.decode(json.encode(response.body));
List<Detail> _detail =
list.map<Detail>((json) => Detail.fromJson(json)).toList();
detailDataSource = DetailDataSource(_detail);
return _detail;
}
Return (full error log)
NoSuchMethodError (NoSuchMethodError: Class 'String' has no instance method 'map'...
I fairly new to this Flutter/Dart but I got the feeling it had something to do with the json, it just I cant get my head over it
Please check your API response because this error generates when there are difference in datatype.
this error says your app response it in String and you are accessing this as map so please check your API response or
try to replace this :
var list = json.decode(json.encode(response.body));
with :
var list = json.decode(response.body);
because json.encode method encodes all list data and that values datatype is String so it gives error.
Replace your function generateDetailList as such:
Future<List<Detail>?> generateDetailList() async {
Uri url = Uri.parse('http://10.0.2.2:81/login_testing/kursus_display.php');
Map<String, String> data = {'usr_id': 'widget.username2'};
http.Response response = await http.post(url, body: json.encode(data));
// var list = json.decode(json.encode(response.body));
var responseMap = await jsonDecode(response.body);
if (response.statusCode == 200) {
List<Detail> _details =
responseMap.map<Detail>((x) => Detail.fromJson(x)).toList();
return _details;
} else {
return null;
}
}
And try not to use var everywhere.

Can not initialize jsonResponse in Flutter project

In my project I get my json string which later on i tried to assign to it a jsonResponse variable but I got an error like : The argument type 'Response' can't be assigned to the parameter type 'String'.
Here's my code:
Future getMahalle() async {
BaseOptions options = new BaseOptions(
baseUrl: globals.PROD_URL,
connectTimeout: 5000,
receiveTimeout: 3000,
);
Dio dio = new Dio(options);
dio.options.headers["Authorization"] = "Bearer ${globals.USER_TOKEN}";
try {
var response =
await dio.get(globals.SELECT_URL); //'api/hizlirapor/selects'
final jsonResponse = jsonDecode(response); //Here is the error line
MahalleModel mahalleList =
MahalleModel.fromJson(jsonDecode(response.data['mahalle']));
return mahalleList;
} on DioError catch (e) {
debugPrint("ERRORR!!!!!!!!!!!!! ${e.error.toString()}");
return null;
}
}
I'm trying to implement this article for example and got stuck. Thanks for help!
You don't have to decode json returned since you are using dio, dio does that for you.
// if it's a single value than try this.
MahalleModel mahalleList = response.data.map<MahalleModel>((mahalle) => MahalleModel.fromJson(mahalle));
// if it's a list than try this.
List<MahalleModel> mahalleList = response.data['mahalle'].map<MahalleModel>((mahalle) => MahalleModel.fromJson(mahalle)).toList();

Dart Future HttpCLientRequest Returns Null

The class Requests set up an HttpClientRequest. The method getTeamsJsonForRequest is supposed to return the JSON response. However, the variable 'return' is not being assigned properly I assum. The print 'CONTS' in the .then response successfully prints the correct response, but printing 'myres' sections says result is null. Not sure why result is not being assigned in the response.transform section.
class Requests {
static Future getTeamsJsonForRequest(String reqPath) async{
var result;
HttpClient myhttp = new HttpClient();
String path = '/api/v3' + reqPath;
myhttp.get('www.thebluealliance.com', 80, path)
.then((HttpClientRequest request) {
request.headers.set("accept", "application/json");
request.headers.set("X-TBA-Auth-Key", "XXXXX");
return request.close();
})
.then((HttpClientResponse response) {
response.transform(utf8.decoder).transform(json.decoder).listen((conts) {
print('CONTS: ' + conts.toString());
result = json.decode(conts).toString();
});
});
print('myres: ' + result.toString());
return result;
}
}
Short answer: avoid using Future.then inside an async method.
Your print is executing before the response comes back. https://www.dartlang.org/tutorials/language/futures#async-await
Without an await any work that is done asynchronously will happen after subsequent statements in this function are executed.
Here is how I'd write this:
Future<String> teamsJsonForRequest(String requestPath) async {
var client = new HttpClient();
var path = '/api/v3$requestPath';
var request = (await client.get('www.thebluealliance.com', 80, path))
..headers.set("accept", "application/json")
..headers.set("X-TBA-Auth-Key", "XXXXX");
var response = await request.close();
var result =
await response.transform(utf8.decoder).transform(json.decoder).single;
print('myres: $result');
return result;
}

How to upload image to server (using POST) which return json in Windows Phone 8.1 RT?

I am making an app which can upload image to a server (the server works well), and I use this method to upload my image to it, but when I get the respond from the result, it return a null string, can you explain for me what did I do wrong.
I followed this method: How to upload file to server with HTTP POST multipart/form-data
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
byte[] bytes = await Converter.GetBytesAsync(storageFile);
form.Add(new ByteArrayContent(bytes, 0, bytes.Count()), "\"upload-file\"", "\"test.jpg\"");
HttpResponseMessage response = await httpClient.PostAsync("my-url", form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
Debug.WriteLine("res: " + sd); // this return a null string
The request return like this:
--a81d2efe-5f2e-4f84-83b9-261329bee20b
Content-Disposition: form-data; name="upload-file"; filename="test.jpg"; filename*=utf-8''%22test.jpg%22
����Ivg?�aEQ�.�����(��9%�=��>�C�~/�QG$�֨������(�`������QE��Z��
Can you help me please!
P/s: Here is my convert method
public static async Task<byte[]> GetBytesAsync(StorageFile file)
{
byte[] fileBytes = null;
if (file == null) return null;
using (var stream = await file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
return fileBytes;
}
This might help
private async Task<string> UploadImage(StorageFile file)
{
HttpClient client = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
form.Add(content, "fileToUpload");
var stream = await file.OpenStreamForReadAsync();
content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = file.Name
};
form.Add(content);
var response = await client.PostAsync("my-url", form);
return response.Content.ReadAsStringAsync().Result;
}
Use ByteArrayContent instead of StringContent. That Should work.
And if you are expecting a stream-response you should use ReadAsStreamAsync instaed of ReadAsStringAsync.

Returning HttpResponseMessage from MVC HttpPost, with content of JSON

My first post on StackOverflow but I am a long time lurker! Hopefully I canget some help on an issue I'm working on.
I am trying to achieve the following. The code below is setting the content to be a JSON string which contains the following...
{
"access_token": "value1",
"expires_in": "value2",
"client_in": null,
"scope": "value3"
}
and here is the code which sends the HttpResponseMessage back to the client.
[HttpPost]
public HttpResponseMessage token(string grant_type,
string code,
string client_id,
string client_secret,
string redirect_uri)
{
WpOAuth2TokenRetValSuccessVM OA2_Success = new WpOAuth2TokenRetValSuccessVM();
OA2_Success.access_token = "value1";
OA2_Success.client_in = client_id;
OA2_Success.expires_in = "value2"; //...The number of seconds left in the lifetime of the token
OA2_Success.scope = "value3"; //...Each access token can have only 1 scope
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
string strJson = JsonConvert.SerializeObject(OA2_Success, Newtonsoft.Json.Formatting.Indented);
StringContent n = new StringContent(strJson, Encoding.UTF8, "application/json");
response.Content = n;
return response;
}
Now then, on the client side for the life of me I cannot get the JSON string back out of the content. Here is the code that I am using to read the content.
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>(str_KEY1, str_VALUE1));
postData.Add(new KeyValuePair<string, string>(str_KEY2, str_VALUE2));
postData.Add(new KeyValuePair<string, string>(str_KEY3, str_VALUE3));
postData.Add(new KeyValuePair<string, string>(str_KEY4, str_VALUE4));
postData.Add(new KeyValuePair<string, string>(str_KEY5, str_VALUE5));
HttpContent content = new FormUrlEncodedContent(postData);
httpClient.PostAsync(strURI, content).ContinueWith(requestTask =>
{
// Get HTTP response from completed task.
HttpResponseMessage response = requestTask.Result;
// Check that response was successful or throw exception
response.EnsureSuccessStatusCode();
// Read response asynchronously as string and write out
var responseValue = response.Content.ReadAsStringAsync();
responseValue.Wait();
string n = responseValue.Result;
var i = 0;
});
Now then, string n's content is as follows, but how do I get at the JSON???
Thanks all.
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Content-Type: application/json; charset=utf-8
}
Sounds like you figured out the problem, but it should be noted that since you're using Web API, there's no need to serialize the data and build the HttpResponseMessage yourself; let the framework do it for you:
[HttpPost]
public WpOAuth2TokenRetValSuccessVM token(string grant_type,
string code,
string client_id,
string client_secret,
string redirect_uri)
{
return new WpOAuth2TokenRetValSuccessVM
{
access_token = "value1",
client_in = client_id,
expires_in = "value2",
scope = "value3"
};
}