AngularJS http.get() accessing json breaks controller - javascript

I'm new to AngularJS and have been trying to parse a json using the $http method. I made a test $scope.test = "working"; variable, which works fine. After putting in my $http method code it stops working and the $http method isn't working either. Here is my json:
{
"programmes":[
{
"#attributes":{
"id":"1"
},
"name":"Arrow",
"imagepath":"..\/img\/arrow.jpg"
},
{
"#attributes":{
"id":"2"
},
"name":"Fargo",
"imagepath":"..\/img\/fargo.jpg"
},
{
"#attributes":{
"id":"3"
},
"name":"You, me and the Apocalypse",
"imagepath":"..\/img\/youme.jpg"
},
{
"#attributes":{
"id":"4"
},
"name":"Heat",
"imagepath":"..\/img\/heat.jpg"
},
{
"#attributes":{
"id":"5"
},
"name":"The Thick of It",
"imagepath":"..\/img\/thick.jpg"
}
]
}
and here is my controller file:
app.controller('MainController', ['$scope', function($scope) {
$scope.test = "works";
$http.get("../../jsons/programmes.json").success(function(response) {$scope.programmes = response.programmes;});
}]);
and finally, my html:
<ul>
<li ng-repeat="x in programmes">
{{ x.name }}
</li>
</ul>
<p>{{test}}</p>
so with the $http.get() in the controller, {{test}} shows up literally, but when I remove it, it shows 'works'. The ng-repeat ul doesn't work at all. What am I doing wrong?

You need to inject the $http angular service in your controller.
You can take a look at your browser console. Generally it gives you a hint on what you missed.
app.controller('MainController', ['$scope', '$http', function ($scope, $http) {
You're seeing the angular expression {{test}} because your missing dependency breaks your controller code.

Related

Show HTML from JSON with Angular

I'm new with Angular, and i am making an application with ionic. I can't show HTML from JSON in my view.
I searched previous questions but still doesn't work. The html code is written as text..
My code
HTML
<div ng-bind-html="bindHTML"></div>
Json
"usuarios": [
{
"nombre": "Name 1",
"description":"<p>Some HTML</p><p>More HTML</p>",
"id": 0
},
{
"nombre": "Name 2",
"description":"<p>Some HTML</p><p>More HTML</p>",
"id": 1
}
]
Controller
.controller('UserCtrl', ['$scope', '$http', '$state', function($scope, $http, $state) {
$http.get('js/data.json')
.success(function(data){
$scope.data = data.usuarios[$state.params.id];
$scope.bindHTML = $sce.trustAsHtml(data.description);
});
}])
Thanks.
I implemented a plunker to illustrate how this works. The only thing I didn't include is the ui.router $state stuff you are doing.
Controller
app.controller('MainCtrl', function($scope, $http, $sce) {
$http.get('data.json').success(function(data){
$scope.data = $sce.trustAsHtml(data.usuarios[0].descripcion);
});
});
View
<body ng-app="plunker" ng-controller="MainCtrl">
<p ng-bind-html="data"></p>
</body>
I'm not sure why yours wouldn't be working if you tried what was suggested in the thread that was marked as duplicate. That would leave me to believe it has something to do with the $state dependency, but hard to tell with out seeing your full app.

Not having it pretty clear about JSON and its uses on Angular

I've got what I consider a very basic question, but I've almost never worked with JSON nor web devolpment (but yes with desktop's with Java), so I'm having really big troubles in my practices with Angular.
You see, I've got this JSON:
{
"imgs": [
{
"title": "Primera foto",
"src": "images/1.gif"
},
{
"title": "Segunda foto",
"src": "images/2.png"
},
{
"title": "Tercera foto",
"src": "images/3.gif"
},
{
"title": "Cuarta foto",
"src": "images/4.jpg"
},
{
"title": "Quinta foto",
"src": "images/5.png"
},
{
"title": "Sexta foto",
"src": "images/6.gif"
}
]
}
I retrieve it using $http and $q via a service, which works greatly. After that, I save the info in a scope variable in a controller:
ctrls.controller('imagesCtrl', ['$scope', 'getJSON', function($scope, getJSON){
$scope.images = [];
$scope.loadImages = function(){
$scope.images = getJSON.getImages();
}
$scope.loadImages();
alert($scope.images);
}])
... and I try to show it in the HTML:
<!DOCTYPE html>
<html ng-app="miApp">
<head>
<meta charset="UTF-8">
<!-- Importamos las dependencias principales !-->
<script src="angular.js"></script>
<!-- <script src="angular-routeangular-route.js"></script> !-->
<!-- Importamos nuestros propios archivos (controladores, directivas, etc...) !-->
<script src="app.js"></script>
<script src="controllers.js"></script>
<script src="directives.js"></script>
</head>
<body ng-controller="imagesCtrl">
<littleImage src="{{image.src}}" ng-repeat="image in images"></littleImage>
</body>
</html>
What am I doing wrong? Nothing appear after the ng-repeat, so I guess I'm not accessing correctly to the JSON data. In case you're doubtious, this is the directive I'm trying to use:
directives.directive('littleImage', function(){
return{
restrict: E,
scope: {
src : "#"
},
template: "<div><img src="+src+" class='img-responsive' alt='Image'></div>"
}
});
In case there are more doubts about my code, this is my service (pretty straightforward):
ctrls.factory('getJSON', ['$http', '$q', function($http, $q){
return{
getImages : getImages
}
function getImages(){
var defered = $q.defer();
var promise = defered.promise;
$http.get("data.json")
.success(function(data){
defered.resolve(data);
})
.error(function(err){
defered.reject(err);
});
return promise;
};
}]);
Anybody knows what am I doing bad?
**EDIT: **
Thanks for the help so far! You helped me a lot, but there's one last thing: now the directive, somehow, isn't computing correctly, and it doesn't wrap it's template into the actual HTML.
This is the HTML:
<div ng-repeat="image in images">
{{image.title}}
<littleImage source="image.src" ></littleImage>
</div>
And this is the directive:
directives.directive('littleImage', function(){
return{
restrict: E,
scope: {
source : "="
},
template: "<div><img ng-src="+source+" class='img-responsive' alt='Image'></div>"
}
});
Any idea on why it doesn't work?
The problem might be in your <img src="..."> Angular has this directive ng-src, because the $scope variable might not be loaded yet when your image tag gets rendered.
I think your problem lies in this line:
<littleImage src="{{image.src}}" ng-repeat="image in images"></littleImage>
The handlebars aren't required and the repeater needs changed, you can simply use:
<littleImage src="image.src" ng-repeat="image in images.imgs"></littleImage>
Your directive is wrong, you should use the normal binding and use an angular expression in the template: src variable doesn't exists, it's src attributes in scope that exists:
directives.directive('littleImage', function(){
return{
restrict: E,
scope: {
src : "="
},
template: '<div><img ng-src="src" class="img-responsive" alt="Image"></div>'
}
});
oh and also in the template, it is binded by angular expression not by text remove the curly braces:
<div ng-repeat="image in images">
{{image.src}}
<littleImage src="image.src" ></littleImage>
</div>
I slightly change your code to check if the data is well loaded, it should help the debug.
you are using Promise.Do this change in controller
getJSON.getImages().then(function(data) {
$scope.images = data.imgs;
}, function() {
//error hanlding part
})
you can't get images array synchronously, you must get it asynchronously.
you must get image list through promise like this:
ctrls.controller('imagesCtrl', ['$scope', 'getJSON', function($scope, getJSON){
$scope.images = [];
$scope.loadImages = function(){
getJSON.getImages().then(function (data) {
$scope.images = data;
})
}
//$scope.loadImages();
//alert($scope.images);
}])
without using of $q and promise way you can using of simple javascript callback to get data from service:
services.factory('getJSON',['$q', '$http', function ($q, $http) {
return {
getImages: function (cb) {
$http({
url: "YOUR_IMAGES_LIST_ADDRESS",
method: 'GET'
}).success(function (data) {
cb(data);
}).error(function (error) {
cb(null, error)
})
}
}
}]);
ctrls.controller('imagesCtrl', ['$scope', 'getJSON', function($scope, getJSON){
$scope.images = [];
$scope.loadImages = function(){
getJSON.getImages(function (data, error) {
if(error) {
//show error
}
$scope.images = data;
})
}
//$scope.loadImages();
//alert($scope.images);
}])
there is another alternative simplest way :), just return $http in your service:
services.factory('getJSON',['$q', '$http', function ($q, $http) {
return {
getImages: function () {
return $http({
url: "YOUR_IMAGES_LIST_ADDRESS",
method: 'GET'
});
}
}
}])
service return promise object of $http.
ctrls.controller('imagesCtrl', ['$scope', 'getJSON', function($scope, getJSON){
$scope.images = [];
$scope.loadImages = function(){
getJSON.getImages().then(function (response) {
$scope.images = response.data;
})
}
//$scope.loadImages();
//alert($scope.images);
}])
Ok! I voted all your posts because every one of them helped me. Thank you for that!
These were my troubles:
I wasn't getting the JSON properly all time, since I use promises. Also, I wasn't accessing to the "imgs" array. Changed my controller function to:
$scope.loadImages = function() {
getJSON.getImages().then(function(data) {
$scope.images = data.imgs;
}, function() {
alert("Ha habido un error cargando los datos");
});
}
The ng-repeat works better in a different div. Also, as you were saying, the src value must be the variable name, instead of its value (as it was being represented by using the curly braces):
{{image.title}}
As last but not least, my directive was totally wrong. Had to access to the src variable in the scope, using "=", change the src from the <img> tag to ng-src, and the last thing that nobody said: instead of writing "src" as its value, it works writing its actual value, via {{src}}:
directives.directive('littleImage', function(){
return{
restrict: "E",
scope: {
src : "="
},
template: ""
}
});
Now it's properly working! Thank you for your help!

Angular factory undefined in controller

I am working on a very simple factory to be used inside an angular controller. The problem is that the factory doesn't seem to be getting picked up inside the controller. The console.log returns undefined and I can't seem to figure out why.
var app = angular.module('App', ['ngRoute', 'ngTouch']);
app.controller('AppController', [
'$scope',
'$rootScope',
'myFactory',
function($scope, $routeParams, myFactory) {
console.log(myFactory)
}]);
app.factory('myFactory', function() {
return 'test';
});
The problem is that your controller is is injecting $rootScope and then you change it to $routeParams in the function. Have a look at this fiddle http://jsfiddle.net/wkqajL2x/6/ where I have removed those two attributes. It then works fine.
var app = angular.module('App', []);
app.controller('AppController', [
'$scope',
'myFactory',
function($scope, myFactory) {
console.log(myFactory)
}]);
app.factory('myFactory', function() {
return 'test';
});
so you just need to decide which one out of those you really want to use.

How can I get JSON from an API into a view of my Angular app?

I have a JSON object that is returning at
localhost:9000/api/
and I'd like that JSON data to populate a view at
localhost:9000/#/query
I've got a route
.when('/query', {
templateUrl: 'views/query.html',
controller: 'QueryCtrl'
})
and a controller:
'use strict';
angular.module('myApp')
.controller('QueryCtrl', ['$scope', 'Query', function ($scope, Query) {
$scope.queries = Query.query();
}]);
and the view:
<h1>Queries</h1>
<ul ng-repeat="query in queries">
<li>{{query}}</li>
</ul>
it seems that either "queries" is empty though, or else the view is just not properly connected to the controller.
The app.js also has this factory:
app.factory('Query', ['$resource', function($resource) {
return $resource('/api', null, {
'update': { method:'PUT' }
});
}]);
The JSON object itself looks like this:
[{"tablename":"acc_logs"},{"tablename":"accounts"},{"tablename":"cat_logs"},{"tablename":"err_logs"},{"tablename":"exp_logs"},{"tablename":"pp_logs"},{"tablename":"sec_logs"},{"tablename":"stl_logs"},{"tablename":"tim_logs"},{"tablename":"tom_logs"},{"tablename":"usage_logs"}]
I can see the JSON string at /api, but when I go to /#/query, it is just an empty list.
How can I connect these? What mistake have I made?
EDIT: Thanks for all the help everyone. I forgot to add my controller javascript in index.html. Rookie mistake, took an hour to fix.
I'm seeing that you are calling the Query object that seems to be unavailable, try:
angular.module('myApp')
.controller('QueryCtrl', ['$scope', 'Query', function ($scope, Group) {
$scope.query = Group.query();
Hope this helps.
As I pointed in the comment, you should change $scope.query = Query.query(); to $scope.queries = Query.query();, as you are using ng-repeat over queries.
However, there are another error. You must change
app.factory('Query', ['$resource', function($resource) {
return $resource('/api', null, {
'update': { method:'PUT' }
});
}]);
to
app.factory('Query', ['$resource', function($resource) {
return $resource('/api/query', null, {
'update': { method:'PUT' }
});
}]);
When you call Query.query() you are requesting a HTTP GET to /api, while you want to request to /api/query.

How to get JSON object (as 'GET') from url using $resource in angularjs

I'm an beginner in angularjs and don't have any idea about web services either. My requirement is something like this:
I have to get a JSON object from my url http://mylocalhostname.dev/users/list?city_id=12
I'm absolutely clueless...Please help me out by modifying my code.
Thanks in advance. Here's my JS code:
'use strict';
var services = angular.module('services', ['ngResource']);
services.factory('dataFactory', ['$resource','$http', '$log',
function ($resource, $http, $log) {
return {
getAllUsers: function(){
return $resource('http://mylocalhostname.dev/users/list',{city_id:12}
,{
locate: {method: 'GET', isArray: true, transformResponse: $http.defaults.transformResponse.concat(function(data, headersGetter)
$log.info(data.UsersList[0]);
return data.UsersList[0].userName;
})}
}
);
}
}
}]);
when i test i get this message in my console :
GET http://mylocalhostname.dev/users/list?city_id=12 200 OK 164ms angular.js (ligne 7772)
(in color red)
(an empty string)
(I realize this is an ancient question, but still unanswered, and it appeared at the top of a search I just did, so hopefully this can close that particular loop)
Simple example of a controller retrieving data from a simple factory, where the factory is using $resource to access a locally-hosted file and returning contents of file back to the controller.
The factory:
'use strict';
angular.module('myApp')
.factory('myFactory', ['$resource', function($resource) {
return function(fileName){
return $resource(fileName, {});
};
}]);
The controller:
'use strict';
var fileToGet = 'some/path/to/file.json';
angular.module('myApp')
.controller('myController', function($scope, myFactory) {
var getDefs = new myFactory(fileToGet).get(function(data) {
$scope.wholeFile = data;
// $scope.wholeFile should contain the entire JSON-formatted object
$scope.someSection = data.section;
// $scope.someSection should contain the "varX" and "varY" items now
$scope.myStringX = JSON.stringify(data.section.varX);
// get the stringified value
});
});
The JSON-formatted file:
{
"someVar": "xyz",
"someArray": [
{
"element0A": "foo",
"element0B": "bar"
},
{
"element1A": "man",
"element1B": "chu"
}
],
"section": {
"varX": 0,
"varY": "yyyy"
}
}

Categories