Strange behavior in angularjs - angularjs

I have a Home page where I display set of data fetched from a $http.get function.
Well, the first time the page loads, it's displayed perfectly, but if you reload the page, it arises the following error:
angular.js:13550 SyntaxError: Unexpected token < in JSON at position 695
at Object.parse (native)
Now, if I go to another page and come back to Home page, it works fine. And if I reload again, it arises the same error.
I'm struggling trying to guess what's happening.
Here I post the init function:
$scope.init = function() {
functions.loading($scope.loading, true);
$scope.$on('loading', function(evt, value) {
$scope.loading.state = value;
});
angular.element(document).ready(function () {
searchService.search_stats().then( function(response) {
FusionCharts.ready(function(){
var last7days = new FusionCharts({
"type": "column2d",
"renderAt": "last7days",
"width": "100%",
"height": "300",
"dataFormat": "json",
"dataSource": {
"chart": {
"caption": "Volume of Searches - Graph",
"subCaption": "Last 7 days",
"xAxisName": "Last 7 days",
"yAxisName": "Volume of searches",
"theme": "fint"
},
"data": response.data.last7days
}
});
last7days.render();
var search_countries = new FusionCharts({
"type": "maps/world",
"renderAt": "search_countries",
"width": "100%",
"height": "400",
"dataFormat": "json",
"dataSource": {
"chart": {
"caption": "Search Volume by Country - Graph",
"subcaption": "Last 7 days ",
"entityFillHoverColor": "#cccccc",
"numberScaleValue": "1,1000,1000",
"numberScaleUnit": "K,M,B",
"numberPrefix": "$",
"showLabels": "1",
"theme": "fint"
},
"colorrange": {
"minvalue": "0",
"startlabel": "Low",
"endlabel": "High",
"code": "#e44a00",
"gradient": "1",
"color": [
{
"maxvalue": response.data.max/2,
"displayvalue": "Average",
"code": "#f8bd19"
},
{
"maxvalue": response.data.max,
"code": "#6baa01"
}
]
},
"data": response.data.countries
}
});
search_countries.render();
functions.loading($scope.loading, false);
});
});
functions.containerResize();
});
search_stats is in a Factory:
search_stats: function(a) {
return $http.get('/api/myFunctions/search_stats/', {cache:false});
}
Any idea?

Well,
Now, at least, I could guess what's happening.
For some strange circumstance, in Chrome was activated Development mode and when switch it off, the page works fine and no error arises now.

Related

Amchart's Serial Chart page gets freezed when used in Ionic

I am using Amchart's serial chart in ionic framework. I have rendered the serial chart using
var chart = AmCharts.makeChart("chartdiv",
{
"type": "serial",
"categoryField": "Name",
"rotate": true,
"angle": 30,
"depth3D": 40,
"startDuration": 1,
"fontSize": 10,
"theme": "default",
"precision": 4,
"creditsPosition": "bottom-right",
"responsive": {
"enabled": true
},
"categoryAxis": {
"gridPosition": "middle",
"title": "Name",
"inside": true
},
"graphs": [
{
"balloonText": "[[title]] of [[Name]]:[[value]]",
"fillAlphas": 1,
"id": "AmGraph-1",
"title": "X",
"type": "column",
"valueField": "X"
},
{
"balloonText": "[[title]] of [[Name]]:[[value]]",
"fillAlphas": 1,
"id": "AmGraph-2",
"title": "Y",
"type": "column",
"valueField": "Y"
},
{
"balloonText": "[[title]] of [[Name]]:[[value]]",
"fillAlphas": 1,
"id": "AmGraph-3",
"title": "Z",
"type": "column",
"valueField": "Z"
}
],
"valueAxes": [
{
"id": "ValueAxis-1",
"title": "Amount"
}
],
"titles": [
{
"id": "Title-1",
"text": "SUMMARY"
}
],
"legend": {
"enabled": true,
"useGraphSettings": true,
"position": "bottom"
},
"dataProvider": $scope.data,
"listeners": [{
"event": "clickGraphItem",
"method": function (event) {
$scope.SelectedX = event.item.category;
$scope.SelectedContext = event.item.dataContext;
$scope.LoadDetailsData($scope.SelectedX, $scope.SelectedContext.Period);
}
}]
}
);
chart.addListener("dataUpdated", zoomChart);
zoomChart();
function zoomChart() {
chart.zoomToIndexes(0, chart.dataProvider.length - (chart.dataProvider.length - 3));
}
I am opening IonicModal on click of graph items and creating another chart. When I close the IonicModal, page which contains the above chart gets freezed untill I press hardware back button.
I am using pie charts few places but not facing this issue on those pages. It seems there is some issue with the serial chart only.
Using IonicModal from template URL option to open Modal -
$ionicModal.fromTemplateUrl('template.html', { scope: $scope })
.then(function (modal) {
$scope.sortModal = modal;
});
$scope.sortShow = function () {
//alert('inside show');
$timeout(function () {
$scope.sortModal.show();
$scope.LoadDetailsChart(); //creating next chart data
}, 0);
};
$scope.sortClose = function () {
$scope.sortModal.hide();
};
$scope.$on('$destroy', function () {
$scope.sortModal.remove();
});
I just need to add paneventenabled property as false here. As per amcharts docs,
This setting affects touch-screen devices only. If a chart is on a page, and panEventsEnabled are set to true, the page won't move if the user touches the chart first. If a chart is big enough and occupies all the screen of your touch device, the user won’t be able to move the page at all. That's why the default value is "false". If you think that selecting/panning the chart or moving/pinching the map is a primary purpose of your users, you should set panEventsEnabled to true.

How can I change the attribute in dataset of Fusionchart?

Hi I am implementing a chart in my Angularjs Application, You can see this plunker http://jsfiddle.net/fusioncharts/73xgmacm/ The thing which I want to achieve is to change the value attribute to profit. How can I do this ? I want to display profit not values.
Regards
After 2 days I finally find out the answer. The thing is You cannot change the Fusionchart attribute value but you can change the attribute of your API once you fetched. I used a loop after I fetched the API and replace the 'profit' attribute with value in this way I made the chart. Yes The thing which i had been ignoring was the use of 'variable' instead of scope. If you see this example you would understand Example Here. I am sharing my code May be it helps someone else too.
Give below is my json array which i called tps.json
[
{
"index": "1",
"variantoption": "fan-green",
"company": "sk fans",
"quantity": "650",
"profit": "78296",
"loss": "8457",
"year": "2016"
},
{
"index": "2",
"variantoption": "fan-white",
"company": "al ahmed fans",
"quantity": "450",
"profit": "78296",
"loss": "8457",
"year": "2016"
},
{
"index": "3",
"variantoption": "fan-purple",
"company": "asia fans",
"quantity": "350",
"profit": "78296",
"loss": "8457",
"year": "2016"
},
{
"index": "4",
"variantoption": "fan-yellow",
"company": "falcon fans",
"quantity": "250",
"profit": "78296",
"loss": "8457",
"year": "2016"
}
]
and here is my controller
$http.get('js/tps.json').success(function (data) {
var chartdata = data;
var arrLength = chartdata.length;
console.log(arrLength);
for (var i = 0; i < arrLength; i++) {
if (chartdata[i]['profit'] && chartdata[i]['index']) {
chartdata[i].value = chartdata[i].profit;
delete chartdata[i].profit;
chartdata[i].label = chartdata[i].index;
delete chartdata[i].index;
console.log(chartdata);
}
}
console.log(chartdata);
FusionCharts.ready(function () {
var tps = new FusionCharts({
type: 'column2d',
renderAt: 'chart-container',
width: '500',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Monthly",
"xaxisname": "Month",
"yaxisname": "Revenue",
"numberprefix": "$",
"showvalues": "1",
"animation": "1"
},
"data" : chartdata
}
});
tps.render();
});
}
);
}
-Stay foolish stay hungry

Add optgroups to angular-selectize asynchronously

I am using angular-selectize directive in my project. For this, I need to load optgroups asynchronously. So far I have tried multiple approaches but none of them works. The problem is, you cannot use the data returned by a promise synchronously. On the flip side, I have also been unable to initialize selectize from inside a promise callback. Given below is the code I currently have. Note that it is only to be used to get the idea of the data I'm playing with, not to present it as something you can consider right.
app.js
$http
.get('/get-categories')
.then(getCategoriesSCB, getCategoriesFCB);
function getCategoriesSCB(response) {
if(typeof(response.data) === 'object') {
posControl.menuCategories = response.data[0];
posControl.menuCategoryGroups = response.data[1];
}
else {
getCategoriesFCB(response);
}
}
function getCategoriesFCB(response) {
console.log(response);
}
posControl.menuConfig = {
valueField: 'id',
labelField: 'title',
placeholder: 'Select Category',
optgroupField: 'class',
optgroupLabelField: 'label',
optgroupValueField: 'value',
optgroups: posControl.menuCategoryGroups,
maxItems: 1,
searchField: ['title', 'category'],
onInitialize: function(selectize) {
console.log('selectize is here');
},
}
index.html
<selectize config="POSCtrl.menuConfig" options="POSCtrl.menuCategories" ng-model="POSCtrl.menuModel"></selectize>
data returned by ajax call
[
// this array has to be used for options.
[{
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855b23f9",
"title": "Beverages"
}, {
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855c05de",
"title": "Cuisines"
}, {
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855cdcb4",
"title": "Steaks"
}, {
"class": "57b83830d0899",
"category": "Wholesale Coffee",
"id": "57b83830d0899",
"title": "Wholesale Coffee"
}],
// this array has to be used for optgroups
[{
"value": "57b83830babb9",
"label": "Food Menu"
}, {
"value": "57b83830d0899",
"label": "Wholesale Coffee"
}]
]
You should be able to load a selectize asynchronously by setting the values directly on the posControl.menuConfig:
function getCategoriesSCB(response) {
if (typeof(response.data) === 'object') {
posControl.menuConfig.options = response.data[0];
posControl.menuConfig.optgroups = response.data[1];
}
}

TypeError: value is undefined angularjs

I have a controller
.controller('ArticlesCtrl', function($scope) {
$scope.sum = function(value) {
return value.reduce(function(total, article) {
return total + article.price;
}, 0);
};
});
and json
[
{"id": "1", "name": "Pizza Vegetaria", "price": 5 },
{"id": "2", "name": "Pizza Salami", "price": 5.5 },
{"id": "3", "name": "Pizza Thunfisch", "price": 6 },
{"id": "4", "name": "Pizza Salami", "price": 5.5 },
{"id": "5", "name": "Pizza Thunfisch", "price": 6 }
]
It works and counts 28 but i get an error in the firebug
watch.js (строка 59)
GET http://192.168.1.136:6543/www/an/articles.json
angular.js (строка 10413)
Error: value is undefined
$scope.sum#http://192.168.1.136:6543/www/an/app.js:43:36
anonymous/fn#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js line 13036 > Function:2:276
expressionInputWatch#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js:14014:31
$RootScopeProvider/this.$get</Scope.prototype.$digest#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js:15548:34
$RootScopeProvider/this.$get</Scope.prototype.$apply#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js:15824:13
done#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js:10263:36
completeRequest#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js:10435:7
requestLoaded#https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.js:10376:1
return logFn.apply(console, args);
Somebody has an idea?
I call the code in the template with {{ sum(articles) }}.
What happens is that since you use
{{ sum(articles) }}
and load data with AJAX request, at the first cycle of template evaluation articles are not yet available. So your sum function tries to call reduce method of the undefined.
The simplest solution is to make sum function return 0 if no articles are available:
$scope.sum = function(value) {
return value && value.reduce(function(total, article) {
return total + article.price;
}, 0) || 0;
};

Why is angularjs code slow?

Is it normal, that angularjs ng-repeat takes 1.5 Seconds to render data from an rest api? The result consists of only 10 rows with in total 1KB of data. How can I improve the speed or where to look for the problem?
ADDED INFOS:
The rest request itself only takes 128ms if I run it directly on the browser.
This is a set of sample data you get from the rest api:
{
"result": [
{
"id": 1224,
"name": "Schokolade-Vanille",
"kcal": 35500,
"displayName": "Schokolade-Vanille"
},
{
"id": 23423,
"name": "Naturreis Uncle Bens",
"kcal": 34400,
"displayName": "Naturreis Uncle Bens"
},
{
"id": 123231,
"name": "Paprikahendl",
"kcal": 4100,
"displayName": "Paprikahendl"
},
{
"id": 434,
"name": "Vanille Kugeln",
"kcal": 53700,
"displayName": "Vanille Kugeln"
},
{
"id": 323423,
"name": "Weihnachtstraum, Lindor-Kugeln",
"kcal": 60800,
"displayName": "Lindor-Kugeln"
},
{
"id": 5435,
"name": "Schokolade",
"kcal": 4300,
"displayName": "Schokolade"
},
{
"id": 23213,
"name": "Hühner-Nuggets",
"kcal": 23400,
"displayName": "Hühner-Nuggets"
},
{
"id": 5534,
"name": "Knödel, Kartoffel",
"kcal": 1230,
"displayName": "Knödel, Kartoffel"
},
{
"id": 23233,
"name": "Curvers",
"kcal": 15400,
"displayName": "Curvers"
},
{
"id": 53434,
"name": "Frites Original",
"kcal": 14100,
"displayName": "Frites Original"
}
],
"count": 12854
}
NEW ADDED INFOS
I have had a closer look now and found out, that not te repeat funktion is the problem.
I used the following code:
$scope.updateResultset = function() {
$scope.result = Food.query({
offset: $scope.offset,
order_by: $scope.orderby,
name: $scope.textfilter,
},function(){
console.log( "response " + (new Date().getTime() - start) );
});
$scope.offset = undefined;
console.log( "updateResultset " + (new Date().getTime() - start) );start = new Date().getTime();
And get the following response:
response 435
But the request itself only takes 131ms. In my opinion, >300ms is a lot of time to waste in a single method?
Compared to my former version, where I showed a plan html list, which was replaced by jquery ajax response html, its much slower?
As others indicated in the comments, the cause in the code is likely something else aside from ng-repeat. However, here are other options to consider, if speed still seems like an issue for ng-repeat:
quick-ng-repeat directive on github: https://github.com/allaud/quick-ng-repeat
ng-scroll, as part of angular-ui: https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md
Ok, I found out the problem. Not the repeatition of the 10 list items was the problem! As you can see in my question, I return not only the 10 results, but also the total amount of results. In my case it was '"count": 12854'.
On the same page, I have a pagination which was the part which slows down the whole page, since it had to render 1286 pager buttons (~12854/10). Now I only show 10 pager-buttons.

Resources