AngularJS - ajax - MVC file multiple upload without form data - angularjs

I am using Flow.JS http://flowjs.github.io/ng-flow/ for file upload.
My requirement is such that I will have to send the following data all in one save button click
multiple files
two string values alongwith the files.
The following way works fine.
Upload ajax call
$scope.UploadFiles = function (flows) {
var data = new FormData();
$.each(flows.files, function (i, flowfile) {
data.append('file' + i, flowfile.file);
});
data.append('message', $scope.Subject);
data.append('subject', $scope.Message);
$.ajax({
url: 'url\savedata',
data: files,
cache: false,
contentType: false,
processData: false,
type: 'POST'
});
}
And my MVC conroller
public JsonResult Savedata()
{
var httpRequest = System.Web.HttpContext.Current.Request;
if(httpRequest.Files.Count != 0)
{
var collection = 0;
foreach (string file in httpRequest.Files)
{
//manipulate file data
}
}
var message = httpRequest.Forms['message'];
var subject= httpRequest.Forms['subject'];
}
All this works fine. I want to know if there is a better way to do this instead of using form data and possibly send all this data using a data model instead, since I need that for some MVC data validations.

Related

Loading xslx file from server to React

Dear fellow developers!
Tell me how to transfer a file with the .xlsx extension from the Spring backend to the React frontend?
Let's get my code first. This is my backend controller which returns a ByteArrayResource:
#PostMapping("/download-report")
public ResponseEntity<ByteArrayResource> generateReport(#RequestBody ReportAttributesWithFiltersDto attributesWithFilters) {
var resource = reportBuilder.generateReport(attributesWithFilters);
var headers = getReportHeaders();
return new ResponseEntity<>(resource, headers, HttpStatus.CREATED);
}
private HttpHeaders getReportHeaders() {
var contentDisposition = ContentDisposition.builder("attachment")
.filename("attachment; filename=my_file.xlsx")
.build();
var headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "force-download"));
headers.setContentDisposition(contentDisposition);
return headers;
}
The backend performs well, if you test it in the development environment, it will return the file in response.
The file downloads fine and there are no problems. Backend shouldn't be a problem.
The problems start when I upload the file on the frontend.
Here is my request:
downloadReport: builder.mutation({
query: (body) => ({
url: paths.downloadReport,
method: "POST",
body: body,
responseHandler: "blob",
}),
}),
What nonsense I get in response, this is some kind of nightmare!
In the case of using a blob, I get this:
res:
data:
undefined
If I set responseHandler: "text", then I get this:
{
"data": "PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u0000\u0000\u0000[Content_Types].xml�S�n�0\u0010����*6�PU\u0015�C\u001f�\u0016��\u0003\\{�X�%����]\u00078�R�\nq�cfgfW�d�q�ZCB\u0013|��|�*�*h㻆},^�{Va�^K\u001b<4�\u00076�N\u0016�\bXQ�dž�9�\u0007!P��$�\u0010�\u0013҆�d�c�D�j);\u0010��ѝP�g��E�M'O�ʕ����H7L�h���R���G��^�'�\u0003\u0007{\u0013�\b�zސʮ\u001bB��3\u001c�\u000b˙��h.�h�W�жF�\u000ej娄CQՠ똈���}ιL�U:\u0012\u0014D�\u0013����%އ����,�B���[�\t��\u001e ;˱�\t�{N��~��X�p�\u001cykOL�\u0004\u0018�kN�V��ܿBZ~����q\u0018��\u000f �a\u0019\u001fr��{O�\u0001PK\u0007\bz��q;\u0001\u0000\u0000\u001c\u0004\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000b\u0000\u0000\u0000_rels/.rels���j�0\f�_���8�`�Q��2�m��\u00014[ILb��ږ���.[K\n\u001b�($}�\u0007�v?�I�Q.���uӂ�h���\u001bx>=��#\u0015��p�H\u0006\"�~�}�\t�n����*\"\u0016\u0003�H�׺؁\u0002��\u0013���8\u0007�Z�^'�#��7m{��O\u0006�3��\u0019�G�\u0006u�ܓ\u0018�'��y|a\u001e�����D�\t��\u000el_\u0003EYȾ�\u0000���vql\u001f3�ML�eh\u0016���*�\u0004��\\3�Y0���oJ׏�\u0003\t:\u0014��^\b�\u001f�}\u0002PK\u0007\b��z��\u0000\u0000\u0000I\u0002\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000docProps/app.xmlM��\n�0\u0010D��\u0010ro�z\u0010�4� �'{�\u000f\b��\u0006�MHV�盓z�\u0019��T��E�1e\u0017�����\u0002Ɇ�ѳ����:�No7jH!bb�Y�\u0007�V���\u0004�����T�)$o���0M��9ؗGb�7�\u0001pe�\u0011�*~�R�>��Y�EB��\u0014�\u0018nW\u0005������\u0000PK\u0007\b6n�!�\u0000\u0000\u0000�\u0000\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0011\u0000\u0000\u0000docProps/core.xmlm��J�0\u0010F_�依�EqC�E�\u0005Aq���w!\u0019�b�C\u0012����u���%��\u001c&_�=�1yG�\u0007�kB��$�����j����\u000b������X\u0013mȶ��e�8�;cх\u0001}\u00125�3ak҇`\u0019�\u0017=*�H�\u0018�\u0018�x�Wׁ��w\bE�����%\u000f\u001cfajW#9)�X��͍�#\n�\u0011\u0015���f\u0014~؀N�\u0007�d%�~X�i���\\��\u0011����ò|:���\u0002IS��L8�\u0001e\u0012\u0005,|���w�T^]�;�\u0014yQ��&�EK7����=W�k~\u0016~��k.c!=&����[�+�Ss�\tPK\u0007\bȂ`�\u0005\u0001\u0000\u0000�\u0001\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0014\u0000\u0000\u0000xl/sharedStrings.xml���J�#\u0014����0d�Bҙ&��!M�\u001b��ӕ�(5�\u0001��L�.�\".*\u0016ԅ��}�x)F{�\u0015μ�'��4\u0005e`����?�93F��9 G��m�-J�\u0014���V�=ۭ\u0016���5Y�J����y#*^�\rP��Hõ\u000f\u001b��$��\bڸ�(Ղ��S�+5�)�W�\\��{�S\u000e�ӯR^���\u001e�YV�\u001cP��\u001cuʶ+�\u0006�M#0�+�a�+$Ї\b\u000f�8�Р�i�X2��#\b}q=3w\u0007a\u001c'�\u0014F�\u000eo(\u001d�M{Z��B0\u001d�6��'D\t�{\u0018�6\u0011\u0017��G�\b]^g���;Z��#���\b��&�H�#�J\u000f�3q���gl�j:�0E�YAN+[鬮j��R�VP��E����6|\u001c1��x�;ޝ�}scI��Y��-�D\u0013YZ�A\u0010{<\"q..\u0012‡x�\u0005x\u0014MD|\u0013��?\bU=SHi�\\.���P�d\u0013���\u000f�'.q\u000f�7���������,N�\u0019�5��_�\u0014\u001f��\rPK\u0007\b��-��\u0001\u0000\u0000�\u0002\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\r\u0000\u0000\u0000xl/styles.xml���n� \u0010��J}\u0007���d���&C%W��J]�9ۨpX#\"�O_0N�L\u001d:����\u001f���n4���ye���UA\t`c�®�\u001f��iKw���aҰ�\u0001\u0002�\u000e�\u0015�C\u0018^\u0018�M\u000fF��\u001d\u0000�Ik�\u0011!��c~p �O&�٦(��\u0011\n)/�dj\u0013<i�\tCE\u000b�x�Z�*k�\u0005^�or\u0016:*i���Xm\u001dQ(a\u0004Y�m�P\u0018�]�B��S3O\u0018��,o�0O��\u0019��%��[��Ii�;Ćf���\b\u0001\u001cֱ K~�\u0006�(Z�������}�91�8�\u0010/>Z'�\u0016nߟ%^jhC48��)\u0006;�t\u0018�51�Jt\u0016�NȋcI\"�\u0001��iu��\u001d{lI���L����_�8ВfL.\u0012�����ƒ����hv���\u000fPK\u0007\b����E\u0001\u0000\u0000�\u0002\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0000\u0000\u0000xl/workbook.xml���N�0\u0010�w$�����\u0001� ��\u0005!uc(�}i��v�3-s\u0017ނ��=�7�I\u0015`d:��������\u001e#��%\u0014\u000b\u0001\f�\u000e��������=,�ˋ�\u0010�n\u0013Žeޓ�6���t�N�\"���\tѩ�c�r�#*C-br\u001d�\u0016�;e=�\re��#4���\u0018��C�Β��J�-��'��=GfT��A�JhTG\b���ͫ�\u0003��cdJ'�ǵ�H\u0010#���S�y2�\u001cJ8}\u000e����5\u001c���\u001a\tqen�M�*�b�̧|~V\u0003PK\u0007\b\u0007$�h�\u0000\u0000\u0000b\u0001\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u001a\u0000\u0000\u0000xl/_rels/workbook.xml.rels��Mk�0\f#���}q��\u0018�n/c����\u0000c+qh\"\u0019K�迟���#\u0007;�$��{\u000f��~Γy�\"#���i� \u0005�#\r\u000e^�O7�`D=E?1�\u0003b�n��8y�?$�YLE�8H���Z\t\tg/\rg����^�\f6�p�\u0003�U���r΀%�좃��\u001d��/\u0003�\u0003I�`|�Rˤ��:f����~\f���mF�\u000bv����\u001c�:���ׯ�������p9HB�Sy\u001dݵK~\u0004�\u0018����\u000bPK\u0007\b�\u0003;��\u0000\u0000\u00003\u0002\u0000\u0000PK\u0003\u0004\u0014\u0000\b\b\b\u0000�,U\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0018\u0000\u0000\u0000xl/worksheets/sheet1.xml��[�� \u0018���?\u0010�+��э��vִ\u0017M6=^3����\u0001fܟ_p\fE�l:���<|/�|���e���rѱ1���B#ǒU��d����]\f��oҙ�g�R*�*\u0018E\u0006[)�;�D�ҁ\b�MtT�f| RMy���)����G�u#4�n�yZu\u0003\u001d����:�\u000f�]�C����\u001f\u001d��5\u0006z�\u0013c�z�ʠR�������T�%?S]��(/\u0016�'\u000e*Z�s/���#�V�/\rէ����b�\u0005C�\u000f\u0000���,�sW�V�\u0002'�q�F8��<\u000bɆ�W��\u000bNTȢ��5L\u0016^���:8����?�\u001a�Q��\n\u0012'v�(�9*X�\u0002\u0013�8��q\nנ�>�$H�w�T�fE&\u000b�ο\u001f9�vq���H���̀�6�M��A5T\u0015\b5��n�.�he�m�m�\u0007��-;��߲G�\u0005[V�,4\f)g#��8^\u0016�W9��ݱ�\u0015��mvع�,޹�,ٹ��s�.�\u001by�uy�\u0015y�y��\u001c7pז�\r�����`珬\u001b4��~&��F\u0001NL�;�^\u001eG��1I����V=qf��Z.� ��gf\u0019K6������4�\u0005PK\u0007\b�Q�.�\u0001\u0000\u0000}\u0005\u0000\u0000PK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,Uz��q;\u0001\u0000\u0000\u001c\u0004\u0000\u0000\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000[Content_Types].xmlPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U��z��\u0000\u0000\u0000I\u0002\u0000\u0000\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000|\u0001\u0000\u0000_rels/.relsPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U6n�!�\u0000\u0000\u0000�\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0002\u0000\u0000docProps/app.xmlPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,UȂ`�\u0005\u0001\u0000\u0000�\u0001\u0000\u0000\u0011\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000i\u0003\u0000\u0000docProps/core.xmlPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U��-��\u0001\u0000\u0000�\u0002\u0000\u0000\u0014\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0004\u0000\u0000xl/sharedStrings.xmlPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U����E\u0001\u0000\u0000�\u0002\u0000\u0000\r\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0006\u0000\u0000xl/styles.xmlPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U\u0007$�h�\u0000\u0000\u0000b\u0001\u0000\u0000\u000f\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\b\u0000\u0000xl/workbook.xmlPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U�\u0003;��\u0000\u0000\u00003\u0002\u0000\u0000\u001a\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u00006\t\u0000\u0000xl/_rels/workbook.xml.relsPK\u0001\u0002\u0014\u0000\u0014\u0000\b\b\b\u0000�,U�Q�.�\u0001\u0000\u0000}\u0005\u0000\u0000\u0018\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000R\n\u0000\u0000xl/worksheets/sheet1.xmlPK\u0005\u0006\u0000\u0000\u0000\u0000\t\u0000\t\u0000?\u0002\u0000\u0000�\f\u0000\u0000\u0000\u0000"
}
What can I be doing wrong?
ok guys,
I found the answer to my question. The thing is, I was using Redux for the request. For some reason it didn't load my file.
Now I switched to fetch request and everything started working
const requestReport = (selectedObj) => fetch(`/api/reports/download-report`, {
headers: new Headers({'content-type': 'application/json'}),
method: "POST",
body: JSON.stringify(selectedObj),
}).

React dropzone, how to upload image?

Using React dropzone, I've successfully accessed the image using the onDrop callback. However, I'm trying to upload to Amazon S3 by sending the image to my server, saving to an S3 bucket, and returning a signed url to the image back to the client.
I can't do this with the information I have so far and the docs don't seem to mention this to my knowledge.
onDrop triggers a function call in my redux actions with the files:
export function saveImageToS3 (files, user) {
file = files[0]
// file.name -> filename.png
// file -> the entire file object
// filepreview -> blob:http:localhost:3000/1ds3-sdfw2-23as2
return {
[CALL_API] : {
method:'post',
path: '/api/image',
successType: A.SAVE_IMAGE,
body: {
name: file.name,
file: file,
preview: file.preview,
username: user
}
}
}
}
However, when I get to my server, I'm not sure how to save this blob image (that's only referenced from the browser.)
server.post('/api/image', (req, res) => {
// req.body.preview --> blob:http://localhost:3000/1ds3-sdfw2-23as2
// req.body.file -> {preview:blob:http://localhost:3000/1ds3-sdfw2-23as2}, no other properties for some reason
})
React Dropzone returns an array of File objects which can be sent to a server with a multi-part request. Depend on the library you use it can be done differently.
Using Fetch API it looks as follows:
var formData = new FormData();
formData.append('file', files[0]);
fetch('http://server.com/api/upload', {
method: 'POST',
body: formData
})
Using Superagent you would do something like:
var req = request.post('/api/upload');
req.attach(file.name, files[0]);
req.end(callback);

Download response as an excel file

File is not downloading at browser. I'm preparing the file and writing it to output stream of response.
Rest API is there:
#RequestMapping(value = "/export-companies",
method = {RequestMethod.GET, RequestMethod.HEAD})
#Timed
public void downloadCompanies(HttpServletResponse response) throws URISyntaxException {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Sample sheet");
Map<String, Object[]> data = new HashMap<String, Object[]>();
data.put("1", new Object[] {"Emp No.", "Name", "Salary"});
data.put("2", new Object[] {1d, "John", 1500000d});
data.put("3", new Object[] {2d, "Sam", 800000d});
data.put("4", new Object[] {3d, "Dean", 700000d});
Set<String> keyset = data.keySet();
int rownum = 0;
for (String key : keyset) {
Row row = sheet.createRow(rownum++);
Object [] objArr = data.get(key);
int cellnum = 0;
for (Object obj : objArr) {
Cell cell = row.createCell(cellnum++);
if(obj instanceof Date)
cell.setCellValue((Date)obj);
else if(obj instanceof Boolean)
cell.setCellValue((Boolean)obj);
else if(obj instanceof String)
cell.setCellValue((String)obj);
else if(obj instanceof Double)
cell.setCellValue((Double)obj);
}
}
try {
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
workbook.write(outByteStream);
byte [] outArray = outByteStream.toByteArray();
response.setContentType("application/ms-excel");
response.setContentLength(outArray.length);
response.setHeader("Expires:", "0"); // eliminates browser caching
response.setHeader("Content-Disposition", "attachment; filename=template.xls");
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();
workbook.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
From front end (using Angular JS):
(function() {
'use strict';
angular
.module('MyApp')
.factory('CompanyExportService', CompanyExportService);
CompanyExportService.$inject = ['$resource'];
function CompanyExportService ($resource) {
var service = $resource('api/export-companies', {}, {
'get': {
method: 'GET',
isArray: false
}
});
return service;
}
})();
File contents are there in response as non-readable format. But file is not downloaded at browser.
Angular will receive the file contents mere character sequences. You need to create a file from these characters and initiate the browser download in frontend.
You can do it like this -
var blob = new Blob([data],
{type: 'application/vnd.openxmlformat-officedocument.spreadsheetml.sheet;'});
saveAs(blob, fileName);
where data is the response you received form your API. The saveAs function is part of FileSaver.js library. Although you can look on how to manually do that but why reinvent the wheel?
Downloading files with XHR is problematic. As long as you do only GET requests, there exists much simpler approach to trigger browser to download file.
Use JavaScript native method window.open(url).
It does work well in all browsers including IE9.
In code below, I use $window, which is Angular's proxy for native window object.
Example for your code could be like:
(function() {
'use strict';
angular
.module('MyApp')
.factory('CompanyExportService', CompanyExportService);
CompanyExportService.$inject = ['$window'];
function CompanyExportService ($window) {
var exportUrl = 'api/export-companies';
return {
download: download
}
function download() {
$window.open(exportUrl);
}
}
})();
Note that this action is out of scope of Angular, you can't do much about error handling or waiting till the file will be downloaded. Might be problem if you want to generate huge Excel files or your API is slow.
For more details, read question: Spring - download response as a file
Update:
I've replaced window.location.href with window.open() which seems to be better choice for downloading files.
If your API will throw an error page instead of file, window.location.href will replace current page (thus losing its state). $window.open() however will opens this error in new tab without losing current state of of application.
You can download file in new tab. Modern browser are closing them automatically when downloading is completed.
By opening new window you get reference to it, when downloading is completed then window.closed is set to true.
Unfortunatelly you need to check from time-to-time this param inside interval ...
var newWindowRef = $window.open(url, name);
if (newWindowRef) {
if (newWindowRef.document.body) { // not working on IE
newWindowRef.document.title = "Downloading ...";
newWindowRef.document.body.innerHTML = '<h4>Your file is generating ... please wait</h4>';
}
var interval = setInterval(function() {
if (!!newWindowRef.closed) {
// Downloading completed
clearInterval(interval);
}
}, 1000);
} else {
$log.error("Opening new window is probably blocked");
}
Tested and works on Chrome v52, FF v48 and IE 11

Angular: can't download server side generated spreadsheet

I'm trying to download a server generated spreadsheet.
My application uses Angular on the front-end and Java on the back-end.
Here's the method on the back-end that receives the request to generate and return the file:
#RequestMapping(value = "download", method = RequestMethod.GET, produces = "application/xls")
public ResponseEntity<InputStreamResource> download() throws IOException {
ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet worksheet = workbook.createSheet("POI Worksheet");
HSSFRow row1 = worksheet.createRow((short) 0);
HSSFCell cellA1 = row1.createCell((short) 0);
cellA1.setCellValue("Hello!");
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFillForegroundColor(HSSFColor.GOLD.index);
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cellA1.setCellStyle(cellStyle);
workbook.write(fileOut);
fileOut.close();
byte[] file = fileOut.toByteArray();
return ResponseEntity
.ok()
.contentLength(file.length)
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(new ByteArrayInputStream(file)));
}
And on the front-end, the following function is executed when the user clicks on Download button:
$scope.exportFile = function() {
$http.get('http://127.0.0.1:8000/api/excel/download')
.success(function (data, status, headers, config) {
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:application/octet-stream;charset=utf-8,' + encodeURI(data),
target: '_blank',
download: 'spreadsheet.xls'
})[0].click();
})
.error(function (data, status, headers, config) {
// handle error
});
};
The returned spreadsheet contains unreadable characters.
If I access http://127.0.0.1:8000/api/excel/download directly, the spreadsheet is downloaded without the .xls extension (with no extension at all). If I rename the file adding the .xls extension and then open it, I can see the file contents. So I think the problem it's on the call Angular does to back-end and not on generating the file on Java.
Has anyone experienced this situation or have some example to share? What am I doing wrong?
The Content-Disposition header should do the trick. So, you would have something like this:
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("Attachment", "spreadsheet.xls");
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(file.length);
return new ResponseEntity<InputStreamResource>(
new InputStreamResource(new ByteArrayInputStream(file)),
headers, HttpStatus.OK);

How to pass query param to parse-rest-api from angularjs $http service?

I'm learning AngularJS , i set-up a development environment using sublime-text as editor and parse.com-rest-api used as back-end layer.
I came across a scenario where, I have to fetch data based on an attribute.
Below given code from the service layer of angularjs has fetch all records from table 'filim'.
var config = {
headers: {
'X-Parse-Application-Id': 'bNtp8FUfr0s1UsAwJr7MFjabCI31HytIuC3gCaJ2',
'X-Parse-REST-API-Key': 'g18cAoH7QkrBZenPqH0pynMKsn6pj4MyfDyIy6X1',
}
};
return {
getFilims: function(callback) {
var filims;
var resp = $http.get('https://api.parse.com/1/classes/filim', config).success(function(data) {
callback(data.results);
});
}
}
I have modified above url to send query-parameter to filter the output, but did not work.
I refer parse.com api doc [ https://www.parse.com/docs/rest#queries ] to modify url to send query - param.
Modified code is given below,
var params = {"where": {"status" : "CLOSED" } }
var resp = $http.get('https://api.parse.com/1/classes/filim?%s' % params, config).success(function(data) {
callback(data.results);
});
But this did not work.
Is this the way to use query-parameter ?
Regards
Ajil
'https://api.parse.com/1/classes/filim?%s' % params
This is a python pattern for interpolating strings and will not work in javascript.
The correct way of combining strings in javascript is:
'https://api.parse.com/1/classes/filim?' + params
Even still, that will probably not work because you'll end up with something like:
'https://api.parse.com/1/classes/filim?[Object object]
What you need to do for parse.com is to JSON encode the query, so try this:
var whereQuery = {"status" : "CLOSED"};
var url = 'https://api.parse.com/1/classes/filim?where=' + encodeURI(JSON.stringify(whereQuery));
var resp = $http.get(url, config).success(function(data) {
callback(data.results);
});

Resources