Unexpected token , in Angular code after $http request - angularjs

I am submitting an $http request to my server using this code below, yet all the of sudden Angular is complaining about an "Unexpected token , " somewhere.
function sendAggrRequestToServer(url) {
var deferred = $q.defer();
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
var retval = data;
deferred.resolve(retval);
}).error(function (data, status, headers, config) {
logErr("Error submitting aggregation request to server: " + status);
});
return deferred.promise;
}
The strange thing is that this exact URL works successfully both in the browser and in Fiddler. And the Json data is returned as expected. However, for some strange reason my javascript code is throwing this
exception:
[app] [HT Error] Unexpected token ,
Object {exception: SyntaxError, cause: undefined}
angular.js:9778
(anonymous function) angular.js:9778
logIt logger.js:55
logError logger.js:49
(anonymous function) logger.js:32
(anonymous function) config.exceptionHandler.js:26
deferred.promise.then.wrappedCallback angular.js:11322
(anonymous function) angular.js:11405
Scope.$eval angular.js:12412
Scope.$digest angular.js:12224
Scope.$apply angular.js:12516
done angular.js:8204
completeRequest angular.js:8412
xhr.onreadystatechange
And my URL is :
http://localhost:49479/api/aggr?sid=9630a8040ee6c901a4034c07894abc317272f855c757a4c60a6a&kri=[CDSStress%20A]:[USD%2010Y%20X%20-1.25],[CDSStress%20A]:[USD%2010Y%20X%201.25]&aggrFunc=SUM([CDSStress%20A]:[USD%2010Y%20X%20-1.25]),SUM([CDSStress%20A]:[USD%2010Y%20X%201.25])&dim=Counterparty
FYI: All appears to be fine in angular.js at this point in angular, and I can indeed see the response data (which is definitely valid Json data). The callback status param has a value of "200" and the statusText is 'OK':
function completeRequest(callback, status, response, headersString, statusText) {
// cancel timeout and subsequent timeout promise resolution
timeoutId && $browserDefer.cancel(timeoutId);
jsonpDone = xhr = null;
// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : urlResolve(url).protocol == 'file' ? 404 : 0;
}
// normalize IE bug (http://bugs.jquery.com/ticket/1450)
status = status === 1223 ? 204 : status;
statusText = statusText || '';
callback(status, response, headersString, statusText);
$browser.$$completeOutstandingRequest(noop);
}
};
Here is a screen image of the break point where I can inspect the "response" param:
However, as soon as it resolves the promise and returns to my calling function, angular throws the Unexpected token error.
I have been using this for days now, but today I must have introduced something to cause this. I just can't figure out what !
Your advice and guidance is greatly appreciated.
regards.
Bob
UPDATE:
I now find Angular throwing the actual exception inside $HttpProvider() on this line :
data = fromJson(data);
inside here :
function $HttpProvider() {
var JSON_START = /^\s*(\[|\{[^\{])/,
JSON_END = /[\}\]]\s*$/,
PROTECTION_PREFIX = /^\)\]\}',?\n/,
CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'};
var defaults = this.defaults = {
// transform incoming response data
transformResponse: [function(data) {
if (isString(data)) {
// strip json vulnerability protection prefix
data = data.replace(PROTECTION_PREFIX, '');
if (JSON_START.test(data) && JSON_END.test(data))
data = fromJson(data);
}
return data;
}],
// transform outgoing request data
transformRequest: [function(d) {
return isObject(d) && !isFile(d) && !isBlob(d) ? toJson(d) : d;
}],
// default headers
headers: {
common: {
'Accept': 'application/json, text/plain, */*'
},
post: copy(CONTENT_TYPE_APPLICATION_JSON),
put: copy(CONTENT_TYPE_APPLICATION_JSON),
patch: copy(CONTENT_TYPE_APPLICATION_JSON)
},
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN'
};
And sendAggregationREquest() is called from here :
function buildAndSendAggregationQuery() {
// iterate list in reportsContext , pass data to to sendAggregationRequest()
var userKRIs = vm.kriUserDataSource.get();
userKRIs.load();
var group;
var kri = '';
var aggrFunc = '';
var aggrKriFuncArray;
var dimension = vm.selectedDimen;
var dimenMulti = '';
var applyScenarioAggr = false;
if (vm.kriUserDataSource.data()[0].group == '99_HSVaR') {
applyScenarioAggr = true;
}
// Call function to build the aggr function. Return value is an array.
if (applyScenarioAggr) {
aggrKriFuncArray = reportsContext.buildAggrFunc(vm.kriUserDataSource.data(), 'AVERAGE');
}
else {
aggrKriFuncArray = reportsContext.buildAggrFunc(vm.kriUserDataSource.data(), 'SUM');
}
kri = aggrKriFuncArray[0];
aggrFunc = aggrKriFuncArray[1];
for (var i = 0; i < vm.multiSelectedDimen.length; i++) {
dimenMulti += vm.multiSelectedDimen[i] + ',';
}
dimenMulti = dimenMulti.substr(0, dimenMulti.length - 1); // ' remove final ","
sendAggregationRequest(kri, aggrFunc, dimension); //dimenMulti);
}
and finally, the response data that comes back from server prior to that exception:
{"status":"SUCCESS", "messages":[], "data":[{"attributes":[{"name":"Counterparty","type":"string"},{"name":"SUM(CDSStress A:USD 10Y X -1.25)","type":"double"},{"name":"SUM(CDSStress A:USD 10Y X 1.25)","type":"double"}],"rows":[{"id":0,"values":["Goldman",0.,0.]},{"id":1,"values":["IBM",0.,0.]},{"id":2,"values":["JP Chase",0.,0.]},{"id":3,"values":["MINESCONDIDA",0.,0.]},{"id":4,"values":["Merrill",0.,0.]},{"id":5,"values":["Nokia",0.,0.]},{"id":6,"values":["Pequot",0.,0.]},{"id":7,"values":["Pimco Fund A",0.,0.]},{"id":8,"values":["Pimco Fund B",0.,0.]},{"id":9,"values":["Deutsche",0.,0.]},{"id":10,"values":["Ditech",0.,0.]},{"id":11,"values":["GM Isuzu",0.,0.]},{"id":12,"values":["GM Opel",0.,0.]},{"id":13,"values":["GMAC",0.,0.]},{"id":14,"values":["GMAC Insurance",0.,0.]},{"id":15,"values":["GSAM",0.,0.]},{"id":16,"values":["General Insurance",0.,0.]},{"id":17,"values":["Genworth",0.,0.]},{"id":18,"values":["AIG",0.,0.]},{"id":19,"values":["Andor",0.,0.]},{"id":20,"values":["BARCLAYS",92.7731197209214,-10.1717767200607]},{"id":21,"values":["BHHSH",0.,0.]},{"id":22,"values":["BHPBFIN",0.,0.]},{"id":23,"values":["BHPSTEEUR",1468.80370935,-161.395632863801]},{"id":24,"values":["BHPSUS",0.,0.]},{"id":25,"values":["BLUESCOPEFIN",0.,0.]},{"id":26,"values":["CSFB",3.35029024626419,-0.367366071961442]},{"id":27,"values":["BLOSOFL",0.,0.]},{"id":28,"values":["GRMOBND",0.,0.]}]}]}

can you make a jsfiddle ? or at least show us how you call the sendAggrRequestToServer method.
It shouldbe
var promise = sendAggrRequestToServer(url);
promise.then(function(data) {
console.log('Success we got: ' + data);
}, function(reason) {
console.log('Failed we got: ' + reason);
}, function(update) {
console.log('Strange we got: ' + update);
});
Thx

Related

throw new ERR_INVALID_ARG_TYPE('chunk',['string','Buffer'],chunk);TypeError[ERR_INVALID_ARG_TYPE]:The "chunk" arg must be type string or Buffer

I am trying to get the contents of a .json file using a node js service into an angularjs method. But am getting following error:
_http_outgoing.js:700
throw new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object
at ServerResponse.end (_http_outgoing.js:700:13)
here are the corresponding code fragments...
angular controller: the commented lines are all of those which i have tried and failed with.
var currentProcess = "process_1cA";
$scope.storestats = [];
var resAss = $resource('/procs/getstorestats');
var stats = resAss.get({
process: currentProcess,
date: date.getFullYear() + "" + m + "" + d
});
stats.$promise.then(function(response) {
if (response != undefined) {
// var r = JSON.parse(response);
//$scope.storestats.push(r);
//$scope.storestats.push(r);
//var r = JSON.parse(response);
$scope.storestats.push(response);
//angular.forEach(r, function(value, key) {
// $scope.storestats.push({key : value});
//});
}
});
NODEJs service:
httpApp.get('/procs/getstorestats', function(req, res, next) {
try {
fs.readFile(cfg.routestatspath + "storestats-"+req.query.process + "-" + req.query.date + ".json", function (err, data) {
var msgs1 = JSON.parse(data);
//var r = data.toString('utf8');
var msgs2 = JSON.stringify(msgs1);
console.log(msgs1);
res.end(msgs1);
});
}
catch (err) {
res.end(err.toString());
}});
P.S: The commented out lines are those which i have tried out with and failed. Also, the commented lines in the node service code snippet, give no error, and when logged show it correctly, but the data when in response of the controllers is blank.
I'm guessing a bit here, but I think you just need to change res.end() to res.send() in your Node code. The "end" method is used when you are streaming chunks of data and then you call end() when you're all done. The "send" method is for sending a response in one go and letting Node handle the streaming.
Also, be sure you are sending a string back!
httpApp.get('/procs/getstorestats', function(req, res, next) {
try {
fs.readFile(cfg.routestatspath + "storestats-"+req.query.process + "-" + req.query.date + ".json", function (err, data) {
var msgs1 = JSON.parse(data);
//var r = data.toString('utf8');
var msgs2 = JSON.stringify(msgs1);
console.log(msgs1);
res.send(msgs2); // NOTE THE CHANGE to `msg2` (the string version)
});
}
catch (err) {
res.send(err.toString()); // NOTE THE CHANGE
}
});
I had a similar error. It was because I was passing process.pid to res.end(). It worked when I changed process.pid to string
res.end(process.pid.toString());
Figured it out. 2 small changes were needed.. One in the controller, which was to use a "$resource.query" instead of "$resource.get". And in the service, as #jakarella said, had to use the stringified part in the .end();
Controller:
var resAss = $resource('/procs/getstorestats');
var stats = resAss.query({process: currentProcess, date: date.getFullYear() + "" + m + "" + d});
stats.$promise.then(function (response) {
$scope.storestats.push(response);
}
Node Service:
httpApp.get('/procs/getstorestats', function(req, res, next) {
try {
fs.readFile(cfg.routestatspath + "storestats-"+req.query.process + "-" + req.query.date + ".json", function (err, data) {
var msgs1 = JSON.parse(data);
var msgs2 = JSON.stringify(msgs1);
console.log(msgs2);
res.end(msgs2);
});
}
If you are using 'request-promise' library set the json
var options = {
uri: 'https://api.github.com/user/repos',
qs: {
access_token: 'xxxxx xxxxx'
},
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function (repos) {
})
.catch(function (err) {
});
Thank you user6184932, it work
try {
await insertNewDocument(fileNameDB, taskId);
res.end(process.pid.toString());
} catch (error) {
console.log("error ocurred", error);
res.send({
"code": 400,
"failed": "error ocurred"
})
}
in mysql2 the reason for the error is the sql word , sql is a query :
const sql = select * from tableName
pool.executeQuery({
sql,
name: 'Error list for given SRC ID',
values: [],
errorMsg: 'Error occurred on fetching '
})
.then(data => {
res.status(200).json({ data })
})
.catch(err => {
console.log('\n \n == db , icorp fetching erro ====> : ', err.message, '\n \n')
})
I got the error using Node v12 (12.14.1).
Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type number
Sample code for context.
const { Readable } = require('stream')
Readable.from(Buffer.from(base64content, 'base64'))
.pipe( ... )
Solution (for my case), was upgrading to Node v14 (14.17.3). e.g.
nvm use 14
nvm

Unexpected token T in JSON at position 0

I am getting this error in console when i click submit button though my data is getting saved to backend as i wanted.
SyntaxError: Unexpected token T in JSON at position 0
at JSON.parse (<anonymous>)
at dc (angular.min.js:91)
at angular.min.js:92
at q (angular.min.js:7)
at gd (angular.min.js:92)
at f (angular.min.js:94)
at angular.min.js:131
at m.$digest (angular.min.js:142)
at m.$apply (angular.min.js:146)
at l (angular.min.js:97)
Here is my frontend code in angular
$scope.nextStep = function() {
if ($scope.selection === 'Information'){
$scope.branch.organisation = $scope.branch.organisation.id;
$scope.fact.incrementStep($scope);
}
else if ($scope.selection === 'Validation'){
var authdata = base64.encode($rootScope.globals.currentUser.user.phone + ':' + $scope.password.password);
if (authdata === $rootScope.globals.currentUser.authdata){
$scope.passwordMatch = true;
var branchArr = [];
var dynamicBranches = $scope.dynamicBranches;
for (var i = 0; i < dynamicBranches.length; i++) {
branchArr.push(dynamicBranches[i].name);
}
var params = [{
"region" : $scope.branch.region,
"branches" : branchArr
}];
Restangular.one('organisation', $scope.branch.organisation).all('add_region_and_branch_data').post(params).then(function(response) {
$scope.createdBranch = response;
$scope.fact.incrementStep($scope);
}, function(error){
///console.log('Error with status', error.statusText, 'code', error.status);
//SweetAlert.swal('Error', 'The agent couldn\'t be created. \n' + error.data.error, 'error');
console.log(error);
});
}else{
$scope.passwordMatch = false;
}
}
};
Again, my data is getting saved to api but I am getting this error. How can i fix this?
Check your HTTP-response body. AngularJS gets something what it can't parse like JSON. May be any warning or error happened and added to your API-response? I thing a problem is not in your nextStep function.
Unexpected token T in JSON at position 0 problem can happen, for example, with this HTTP-responses:
Too many params warning{"here": "is valid JSON"}
Or just warning
Too many params warning

The current request is not a multipart request in angularJS and Spring Rest

I am trying to upload file using AngularJS on client side and Spring RESTApi on server side but getting
Error
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.assertIsMultipartRequest(RequestParamMethodArgumentResolver.java:216)
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:167)
.......
[http-bio-8080-exec-1] WARN org.springframework.web.servlet.PageNotFound - Request method 'POST' not supported
Rest API
Below is a simple Java Post function:
#RequestMapping(method = RequestMethod.POST)
public String saveFile(
#RequestParam("file") MultipartFile file) {
return "success";
}
In Angular, I am using Resource service to send request.
Chrome Developer Tool output
Request Payload
------WebKitFormBoundarydFRgXclyfPVixdHo
Content-Disposition: form-data; name="file"; filename="Release_Notes.txt"
Content-Type: text/plain
------WebKitFormBoundarydFRgXclyfPVixdHo--
Angular Service
function FileUploadService($resource) {
return $resource('/fileUpload/:id', {}, {
'save' : {
method : 'POST',
transformRequest: function(data, headersGetter) {
var headers = headersGetter();
headers['Content-Type'] = undefined;
if (data == undefined) {
return data;
}
var fd = new FormData();
var createKey = function(_keys_, currentKey) {
var keys = angular.copy(_keys_);
keys.push(currentKey);
var formKey = keys.shift()
if (keys.length) {
formKey += "[" + keys.join("][") + "]"
}
return formKey;
};
var addToFd = function(object, keys) {
angular.forEach(object, function(value, key) {
var formKey = createKey(keys, key);
if (value instanceof File) {
fd.append(formKey, value);
} else if (value instanceof FileList) {
if (value.length == 1) {
fd.append(formKey, value[0]);
} else {
angular.forEach(value, function(file, index) {
fd.append(formKey + '[' + index + ']', file);
});
}
} else if (value && (typeof value == 'object' || typeof value == 'array')) {
var _keys = angular.copy(keys);
_keys.push(key)
addToFd(value, _keys);
} else {
fd.append(formKey, value);
}
});
};
addToFd(data, []);
return fd;
}
}
});
}
Any hint to avoid this error?
Method assertIsMultipartRequest from RequestParamMethodArgumentResolver class is called.
The method asserts that it is a post request and content type starts with multipart/
if (!"post".equals(request.getMethod().toLowerCase())) {
return false;
}
String contentType = request.getContentType();
return (contentType != null && contentType.toLowerCase().startsWith("multipart/"));
Your content type, on the other hand, is
Content-Type: text/plain
And an exception is thrown.
#RequestMapping(method = RequestMethod.POST)
your value attribute is missing in the requestmapping it should be like this
#RequestMapping(value="/fileupload/save/{id}" ,method = RequestMethod.POST)
and use this code when creating angular resource
$resource('fileupload/save/:id',
{id:'1'}, {
save: {method:'POST', params:{charge:true}}
});
in springBoot theres not much to configure when uploading the file.
but you can add these properties to your application property file to change the file size limits.
# File size limit
multipart.maxFileSize = 3Mb
# Total request size for a multipart/form-data
multipart.maxRequestSize = 20Mb
The above issue is resolved by:
1) Creating a MultipartResolver bean in WebAppConfig.java as shown below:
#Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
return multipartResolver;
}
2) Replacing AngularJS FileUploadService (which is using Resource service) with http as shown below:
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
});
Hope it helps.

Incorrect syntax.. probably missing one minor detail

Sending an http request form angular to spring and I'm getting the syntax is incorrect response. Whats weird is I'm not doing anything special and this same formula is working in 100 other places.. any help is much appreciated
"NetworkError: 400 Bad Request - http://localhost:8080/accounts/1/groups/GroupedDisplay"
The request sent by the client was syntactically incorrect.
Java
#RequestMapping(value = "/accounts/{accountId}/groups/{groupName}", method = RequestMethod.POST)
public JSONObject createGroup(#RequestBody Display display, #PathVariable("accountId") Long accountId, #PathVariable("groupName") String groupName) {
return JsonResponse.generateResponse("display", groupService.createGroup(accountId, groupName, display), null);
}
Angular
function getUrl(suffix) {
if (suffix)
return 'http://localhost:8080/accounts/'+getAccountId()+'/groups/'+suffix;
else
return 'http://localhost:8080/accounts/'+getAccountId()+'/groups';
}
...
createGroup: function(groupName, display) {
var deferred = $q.defer();
$http.post(getUrl(groupName), display)
.success(function (response) {
var display = response.data.display;
deferred.resolve(new Display(display));
})
.error(function(response) {
deferred.reject('Failed to retrieve display: ' + response.message);
});
return deferred.promise;
},

capturing full URL of a GET request in AngularJS including query params

I'm using http interceptor. I do see all the values when I make a Restangular GET request. Here is the code for my request interceptor.
request: function (config) {
// see link below to see value of config
console.log('config', config);
// below returns full url except query string
console.log('location', $location.absUrl());
// $rootScope.cacheData is $cacheFactory
console.log('$rootScope', $rootScope.cacheData);
// only returns {id: "http", size: 3}
console.log('cache info', $rootScope.cacheData.info());
// below returns undefined
console.log('cache get', $rootScope.cacheData.get('http'));
// other codes removed since it's not related
// ........
// ........
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
config value : http://i.imgur.com/l0IsXbJ.png
Unfortunately, preparing the params captured manually is not 100% guaranteed that it will match what has been cached. I noticed that cacheFactory checks the exact string that was requested. So if our GET request's query parameters are age=12&name=scott then on our http interceptor, we prepare it the other way by putting name first then age(name=scott&age=12), cacheFactory won't find it.
So I'm trying to look for an angular service or factory that will return the full URL equal to the request we made. I tried $location but it's not giving the full GET request.
I just decided to parse the config and build it from scratch. It's working great :)
if ( config.method == 'GET' && (config.url.indexOf('v1/repeters') != -1) ) {
// Prepare the full path
var cachedUrlsLocalStorage;
var absolutePath = '';
_(config.params).keys().sort().each( function(key, index) {
var value = config.params[key];
absolutePath = absolutePath + key + '=' + value + (index < _(config.params).keys().value().length - 1 ? '&' : '');
});
cachedUrlsLocalStorage = JSON.parse(window.localStorage.getItem('cachedUrls'));
if (cachedUrlsLocalStorage) {
var exists = _.findIndex(cachedUrlsLocalStorage, function(cachedData) {
return cachedData.url == config.url + '?' + absolutePath;
});
if (!exists) {
cachedUrlsLocalStorage.push({url : config.url + '?' + absolutePath, timeExecuted : moment(), expiryTime : moment().add(10, 'minutes')});
window.localStorage.setItem('cachedUrls', JSON.stringify( cachedUrlsLocalStorage ));
}
} else {
cachedUrlsLocalStorage = [];
cachedUrlsLocalStorage.push({url : config.url + '?' + absolutePath, timeExecuted : moment(), expiryTime : moment().add(10, 'minutes')});
window.localStorage.setItem('cachedUrls', JSON.stringify( cachedUrlsLocalStorage ));
}
}

Resources