Why Angular's $http.get service not working? - javascript

I'm having trouble with an example I found on W3Schools about Angular services, on this specific case $http.get one.
I have a json.php file where I have the next JSON:
{
"bands": [
{
"name": "Red hot chilli peppers",
"year": "2009",
},
{
"name": "Maroon 5",
"year": "2005",
},
{
"name": "ACDC",
"year": "2000",
}
]
}
And the Angular and HTML code which should iterate over the object and show the data in it, but it's not working:
JavaScript
var serviceTestApp = angular.module('myapp3', []);
serviceTestApp.controller('controller3', function($scope, $http){
$http.get('json.php').then(function(response){
$scope.myData = response.data.bands;
});
});
HTML
<div ng-app='myapp3' ng-controller='controller3'>
<ul>
<li ng-repeat='x in myData'>
{{x.name}}
</li>
</ul>
</div>
What am I doing wrong here? I use Angular 1.5.0

When you mean not working what exactly do you mean? Do you mean it's successful but doesn't return what you want? In which case you're probably pointing at the wrong thing in the object.
Or does it throw an error?
You should structure it like this:
$http.get('json.php').then(function(response){
// Place a debugger statement here to see if it's successful
$scope.myData = response.data.bands;
}, function(error) {
// No breakpoint needed as you'll see the error in the console window
console.error(error);
});
One other reason could be that you don't have the file in the right place. json.php means that I'd expect it to be in the same folder as the controller.

Related

Why am I getting an error, "ReferenceError: categories is not defined" in AngularJS?

In my understanding, $scope.categories is already defined. Then why am I getting this error and not able to access data from the Json file?
Here is my controller:
(function(){
app.controller('productsCtrl', ['$scope','$cookies', '$http', function($scope,$cookies,$http){
$http.get("controllers/data.json").then(function (response) {
$scope.categories = response.data;
});
$scope.specials = [categories[0].laptops[1], categories[1].accessories[0]];
}]);
})();
Here is my Json file:
[
{
"laptops": [
{
"name": "Asus Laptop",
"price": 300
},
{
"name": "HP Notebook",
"price": 200
}
]
},
{
"accessories": [
{
"name": "WD Hard Drive",
"price": 100
},
{
"name": "WD Blue SSD",
"price": 700
}
]
}
]
You have assigned response data into $scope.categories, you need to use $scope.categories instead of categories and also you should add into $scope.specials once http call completed like
(function(){
app.controller('productsCtrl', ['$scope','$cookies', '$http', function($scope,$cookies,$http){
$scope.specials = [];
$http.get("controllers/data.json").then(function (response) {
$scope.categories = response.data;
$scope.specials.push($scope.categories[0].laptops[1]);
$scope.specials.push($scope.categories[1]. accessories[0]);
});
}]);
})();
There's actually a few issues here. First is you never define a variable named categories, you have a property of the $scope object named that, so you need to access $scope.categories or the response.data setting it directly.
Second, you have a race condition issue. You are trying to access the values of categories outside the promise, meaning potentially before the get request has returned any data. When you use get().then() like you are, the code after the request doesn't wait for the request to finish before it runs, so whatever is faster runs first. Because one of the two operations running is accessing an external endpoint and the other is local javascript code, the flow is almost guaranteed to be this:
send get request to "controllers/data.json"
set $scope.specials - causing your undefined error
set $scope.categories when get request promise resolves
You need to access the categories inside the promise to guarantee that it actually has been defined at the point you are trying to access it:
$http.get("controllers/data.json").then(function (response) {
$scope.categories = response.data;
$scope.specials = [$scope.categories[0].laptops[1], $scope.categories[1].accessories[0]];
});
It's also generally a bad idea to hard code indexes like this, if the data changes you run into a possible index out of bounds error.

Why isn't list of elements showing up?

I am working on an AngularJS tutorial
This tutorial covers the ng-repeat directive, an AngularJS directive used repeating data.
To show an example of ng-repeat, The author enters periodic table elements in a JSON format, covering element's name, element #, etc into controller logic($scope)
To display the elements(code below), the author simply used the directive with a html un-ordered list
<ul>
<li data-ng-repeat="element in periodic.elements">{{element.name}} </li>
</ul>
I tried doing the same JsFiddle but the list of elements isn't showing up, only {{element.name}}
At first I thought this was an AngularJS syntax issue but I checked over the scope attribute, if the controller names match, etc.... I made sure to enable the AngularJS option in JsFiddle as well.
Does anyone know what the issue is or why this list isn't showing up?
You forget completing controller sytax '});' at the end of the code.
'use strict';
var chemistryApp = angular.module('chemistryApp', []);
chemistryApp.controller(
'chemistryController',
function chemistryController($scope) {
$scope.periodic = {elements: [
{
"atomicNumber": 1,
"name": "Hydrogen",
"atomicWeight": 1.00794,
"phase": "Gas",
"ionization": 13.5984,
"melting": -259.15,
"boiling": -252.87
},
{
"atomicNumber": 2,
"name": "Helium",
"atomicWeight": 4.002602,
"phase": "Gas",
"ionization": 24.5874,
"melting": 0,
"boiling": -268.93
},
{
"atomicNumber": 3,
"name": "Lithium",
"atomicWeight": 6.941,
"phase": "Solid",
"ionization": 5.3917,
"melting": 180.54,
"boiling": 1342
}
]
};
});
Working Fiddle

AngularJS How to use RESTful with factory module

I have been getting an error to make RESTful code for 2 hours.
I have one file has a controller here
angular.module('orderToBeShippedApp',['ng','projectService'])
.controller('orderCtrl',function($scope, Project){
Project.query(function(data){
alert(data);
$scope.projects = data;
});
});
Here is my fatory which is called 'project'.
angular.module('projectService',['ng','ngResource'])
.factory('Project',function($resource){
return $resource('api/url/:projectId.json',{},{
query:{
method:'get',
params: {projectId:"test"},
isArray: false
}
});
});
My html:
<div ng-controller = "orderCtrl" class ="col-sm-8 col-md-9">
<!--Body content -->
<div ng-repeat = "project in projects">
<h2>{{project.name}}</h2>
</div>
</div>
My json is something like
[
{
"age": 0,
"id": "a",
"imageUrl": "a0.jpg",
"name": "b",
"snippet": "Tbaa."
},
{
"age": 1,
"id": "mo",
"imageUrl": "assets/images/phones/mo.0.jpg",
"name": "M\u2122",
"snippet": "The Ned by Android 3.0 (Honeycomb)."
}
]
It doesn't give me any error message on the browser. it seems having a problem on factory function.
Could anyone help me to fix it?
You should change your binding to be name, not ProjectName based on your model definition:
<div ng-controller = "orderCtrl" class ="col-sm-8 col-md-9">
<!--Body content -->
<div ng-repeat = "project in projects">
<h2>{{project.name}}</h2>
</div>
Also, to use ngResource you need to remember to add a script reference to: angular-resource:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular-resource.min.js"></script>
UPDATE:
Remove 'ng' Dependency
Pass the resource to the controller as a dependency.
// resource
angular.module('projectService',['ngResource'])
.factory('Project',function($resource){
return $resource('api/url/:projectId.json',{},{
query:{
method:'get',
params: {projectId:"test"},
isArray: false
}
});
});
// controller
angular.module('orderToBeShippedApp',['projectService'])
.controller('orderCtrl',['$scope','Project', function($scope, Project){
Project.query(function(data){
alert(data);
$scope.projects = data;
});
}]);
Your factory may not be giving a console error however it may not be able to bring back the data. Your factory should be looking like this:
angular.module('projectService',['ng','ngResource'])
.factory('Project',function($resource){
return {
projects: $resource('api/url/:projectId.json', {projectId: '#test'})
}
});
}]);
In your controller it should invoke the method like this:
angular.module('orderToBeShippedApp',['ng','projectService'])
.controller('orderCtrl',['$scope','Project',function($scope, Project){
$scope.projects = Project.projects.get({id: 'test'});
}]);
UPDATE:
In order to relax chrome the xmlHttpRequest error you need to run this command from the chrome.exe folder of your machine:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security

AngularJS assign variables to view's scope

I have a somewhat deep JSON object I am trying to using in an HTML template.
{
"service": {
"name": "example",
"url": "abc.com",
"template": "/abc/def/v1",
"metadata": {
"password": "dontguessme",
"username": "supereasy"
}
}
}
I am including a template with the following HTML code.
<div class="modal-body" ng-include="service.instructionsTemplate"> </div>
In the template there is the following.
<h1>Some example content</h1>
{{service.metadata.password}}
My question is instead of referencing the field password via service.metadata, is there a way I can reference it with just the variable password.
I was trying to dig through some of the Angular docs around scoping and templates but came up empty. I saw you can use ng-init.
I was able to use ng-init="metadata = service.metadata" and was able to reference the field password in the template via metadata.password.
However I would just like to reference it by password.
Any ideas?
You already did ng-init="metadata = service.metadata", why not going a step further and do ng-init="password = service.metadata.password"?
Another way would be to bind $scope.password = service.metadata.password inside the controller thayou're using on that page
Edit: OP asked a more general solution
If you don't know the property names, then your best move would be to bind the metadata object, like you already did, and then iterate through its properties using ng-repeat
in your controller:
$scope.metadata = service.metadata
in your template (view):
<h1>Some example content</h1>
<ul>
<li ng-repeat="element in metadata">{{element}}</li>
</ul>
You can easily set the password to something inside the controller:
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.data = {
"service": {
"name": "example",
"url": "abc.com",
"template": "/abc/def/v1",
"metadata": {
"password": "dontguessme",
"username": "supereasy"
}
}
};
$scope.password = $scope.data.service.metadata.password;
});
Here is a demo: http://plnkr.co/edit/KrKeLIP2ANd0rl5NLywF?p=preview

p.then is not a function, error with angular parser?

I have the next Json:
[{
"given": "given3",
"when": "when3",
"then": "then asjdh"
}, {
"given": "given1",
"when": "when1",
"then": "then asjdh"
}, {
"given": "given2",
"when": "when2",
"then": "then asjdh"
}]
and when I try to do:
<ul class="phones">
<li ng-repeat="behavior in behaviors" >
<p>GIVEN: {{behavior.given}}</p>
<p>WHEN: {{behavior.when}}</p>
<p>THEN: {{behavior.then}}</p>
</li>
</ul>
I have the next error:
Error: p.then is not a function
anonymous#file:/~/app/lib/angular/angular.js:6531
lex/readIdent/token.fn<#file:/~/app/lib/angular/angular.js:5914
$interpolate/fn#file:/~/app/lib/angular/angular.js:4931
Scope.prototype.$digest#file:/~/app/lib/angular/angular.js:7889
Scope.prototype.$apply#file:/~/app/lib/angular/angular.js:8097
done#file:/~/app/lib/angular/angular.js:9111
completeRequest#file:/~/app/lib/angular/angular.js:9274
createHttpBackend/</xhr.onreadystatechange#file:/~/app/lib/angular/angular.js:9245
"
well i don't understand so much about how angular parse the information in json, but i think "then" is a reserved word, or something like that?
Any suggestion?
The problem is that then is used in the promise API and you are using it as a data key for your model. It sees that "then" is defined and tries to execute it, but then is a string, not a function.
Promise API
well... i solved using a simple replace in the controller.
/* Controllers */
function behaveListCtrl($scope, $http) {
$http.get('behaveMe/behaves.json').success(function(data) {
for(var i in data){
data[i].Then = data[i].then;
delete data[i].then;
}
$scope.behaviors = data;
});
}

Categories

Resources