Deserialise JSON String to object using AngularJS using Generic Ionic
I am following this AngularJS Learning Tool .
I can successfully display a list of arrays of data models in the browser (Chrome 37.0.2062.94) when instantiated using document object notation where $ scope.sentences is of type Object.
Controller: (extract)
'use strict';
angular.module('YeomanIonic.controllers', [])
.controller('MapCtrl', ['$scope', '$ionicLoading', '$http', function($scope, $ionicLoading, $http) {
$scope.sentences = [
{"name": "Hello",
"snippet": "1"
},
{"name": "Goodbye",
"snippet": "2"
}
];
}]);
View (extract):
<body ng-app="YeomanIonic" ng-controller="MapCtrl">
<ul>
<li ng-repeat="sentence in sentences">
<span>{{sentence.name}}</span>
<p>{{sentence.snippet}}</p>
</li>
</ul>
But I am having problems when I instead store this array of hashes in a JSON file (i.e. app / data / sentences.json) like this:
sentences.JSON:
[
{"name": "Hello",
"snippet": "1"
},
{"name": "Goodbye",
"snippet": "2"
}
];
I am trying to use the AngularJS $ http service to make an HTTP GET request to fetch JSON data. The manual mentions that AngularJS automatically detects and parses the JSON response and that the $ http service returns a promise object using the success method. So I assumed that the following code would work correctly so that $ scope.sentences would be of type "Object", however it tells me that it is of type "String".
$http({
method: 'GET',
url: 'data/sentences.json'
}).
success(function(data, status, headers, config) {
console.log("HTTP Request - Success");
$scope.sentences = data;
console.log(typeof($scope.sentences));
}).
error(function(data, status, headers, config) {
console.log("HTTP Request - Error");
});
So, I tried to assign it with the following code, which gives the following error:
$scope.sentences = angular.fromJson(data);
SyntaxError: Unexpected token ;
at Object.parse (native)
at Object.fromJson (http://127.0.0.1:9000/bower_components/angular/angular.js:1139:14)
at http://127.0.0.1:9000/scripts/controllers.js:34:59
at http://127.0.0.1:9000/bower_components/angular/angular.js:8105:11
at wrappedCallback (http://127.0.0.1:9000/bower_components/angular/angular.js:11561:81)
at wrappedCallback (http://127.0.0.1:9000/bower_components/angular/angular.js:11561:81)
at http://127.0.0.1:9000/bower_components/angular/angular.js:11647:26
at Scope.$eval (http://127.0.0.1:9000/bower_components/angular/angular.js:12673:28)
at Scope.$digest (http://127.0.0.1:9000/bower_components/angular/angular.js:12485:31)
at Scope.$apply (http://127.0.0.1:9000/bower_components/angular/angular.js:12777:24) angular.js:10061
I'm trying to use an alternative with the quoted quotes that gives the following error (which gets confused with the "d" in the word "data"):
$scope.sentences = angular.fromJson('data');
SyntaxError: Unexpected token d
at Object.parse (native)
at Object.fromJson (http://127.0.0.1:9000/bower_components/angular/angular.js:1139:14)
at http://127.0.0.1:9000/scripts/controllers.js:34:59
at http://127.0.0.1:9000/bower_components/angular/angular.js:8105:11
at wrappedCallback (http://127.0.0.1:9000/bower_components/angular/angular.js:11561:81)
at wrappedCallback (http://127.0.0.1:9000/bower_components/angular/angular.js:11561:81)
at http://127.0.0.1:9000/bower_components/angular/angular.js:11647:26
at Scope.$eval (http://127.0.0.1:9000/bower_components/angular/angular.js:12673:28)
at Scope.$digest (http://127.0.0.1:9000/bower_components/angular/angular.js:12485:31)
at Scope.$apply (http://127.0.0.1:9000/bower_components/angular/angular.js:12777:24) angular.js:10061
I am trying this third alternative which gives the same as the previous error:
$scope.sentences = window.JSON.parse('data');
I'll try the fourth option, which also gives the same as the previous error:
$scope.sentences = JSON.parse('data');
With a little bit of hope, I came across this [lifesaver post] ( stackoverflow ) which mentions the use of eval ('data') but also mentions that it poses a security risk, but I gave him a chance:
$scope.sentences = eval(data);
And it works !! It successfully captures and displays data from the JSON file as a list in the browser. Note that when I check what it assigns with console.log (eval (data)); this gives me [object-object], [object-object], [object-object], [object-object]
But I can't celebrate because I don't understand why the other alternatives I've tried haven't worked ...
So my community questions:
- Why doesn't AngularJS $ http service detect and parse the JSON response automatically and return it as an object (instead of a string)?
- Why does AnglerJS fromJSON deserialize JSON string without error? (which appears to just execute JSON.parse ('') according to its source code )
- Is my JSON encoding competent and my inputs incorrectly validated in this simple example? Is this why only the unsafe "eval" method (with its associated security risks) works for me?
FYI, Here is the latest commit of my Ionic app linked to this post on GitHub
source to share