Can't display in console log a Angular object value with controller - javascript

I'm beginner in AngularJS and so I try to learn this framework.
To train, I use a REST API with Star Wars data (https://swapi.co/).
I have a problem : i can't display a value of object in console log.
See my Angular JS code :
var pokeApp = angular.module('pokedex', ['ngResource']);
pokeApp.config(['$resourceProvider', function($resourceProvider) {
$resourceProvider.defaults.stripTrailingSlashes = false;
}]);
pokeApp.controller('PokeController', function ($scope,$log, People) {
$scope.people = null;
$scope.getPeople = function(idPeople) {
$myPeople = People.get({id:idPeople});
$log.log($myPeople.name); // result in console : undefined
$scope.people = $myPeople;
$log.log($scope.people.name); // result in console : undefined
};
});
pokeApp.service('People', function($resource)
{
$jsonPeople = $resource('https://swapi.co/api/people/:id', {id:'#id'});
return $jsonPeople;
});
And see my HTML code :
<body ng-app="pokedex">
<div class="container" ng-controller="PokeController">
<h1>Star Wars Engine</h1>
<div>
<input ng-model="idPeople"/>
<button ng-click="getPeople(idPeople)">Search</button>
</div>
<br />
<div>
<table border="1" class="tableSW">
<tr>
<th>Nom</th>
<th>Sexe</th>
<th>Taille</th>
<th>Poids</th>
<th>Date de naissance</th>
<th>Couleur de peau</th>
</tr>
<tr>
<td>{{ people.name }}</td>
<td>{{ people.gender }}</td>
<td>{{ people.height }}</td>
<td>{{ people.mass }}</td>
<td>{{ people.birth_year }}</td>
<td>{{ people.skin_color }}</td>
</tr>
</table>
</div>
</div>
<!-- Dependencies -->
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/angular-resource.min.js"></script>
<script src="js/pokedex.js"></script>
<style>
.tableSW td{
width: 150px;
}
.tableSW th{
width: 150px;
}
</style>
</body>
When i try to display value of my object from API in the console, it contains "undefined".
I don't understand why, can you explain me ?
I specify the display of informations in the view works very well.
Thanks a lot.
Simon.

For information, I can display the json of the object in the console ($log.log($myPeople)) :
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.co/api/planets/1/",
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/6/",
"https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/",
"https://swapi.co/api/films/7/"
],
"species": [
"https://swapi.co/api/species/1/"
],
"vehicles": [
"https://swapi.co/api/vehicles/14/",
"https://swapi.co/api/vehicles/30/"
],
"starships": [
"https://swapi.co/api/starships/12/",
"https://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.co/api/people/1/"
}
But, it's impossible to display the name of other attribute of this object ...
$log.log($myPeople.name) returns "undefined" in console

The $resource service performs an asynchronous HTTP call. It doesn't return your data right away, instead it returns an empty object. A callback function should be passed as the second argument and it will be called when your data is available. Something like this should work.
$scope.getPeople = function(idPeople) {
$myPeople = People.get({id:idPeople}, function() {
$log.log($myPeople.name); // result in console : undefined
$scope.people = $myPeople;
$log.log($scope.people.name); // result in console : undefined
});
};
You should review the documentation on $resource on the angularjs website.
https://docs.angularjs.org/api/ngResource/service/$resource

Related

AngularJS Binding doesn't seem to work

I'm fairly new to Angular, and a simple binding doesn't work for me.
It just shows me {{ trip.name }} and {{trip.created}} just as they're written.
My controller:
(function () {
"use strict";
angular.module("app-trips")
.controller("tripsController", tripsController);
function tripsController() {
var vm = this;
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created = new Date()
}];
A part of my class:
#section Scripts {
<script src="~/lib/angular/angular.min.js"></script>
<script src="~/js/app-trips.js"></script>
<script src="~/js/tripsController.js"></script>
}
<div class="row" ng-app="app-trips">
<div ng-controller="tripsController as vm" class="col-md-6 col-md-offset-3">
<table class="table table-responsive table-striped">
<tr ng-repeat="trip in vm.trips">
<td>{{ trip.name }}</td>
<td>{{ trip.created }}</td>
</tr>
</table>
</div>
the view of the controller:
(function () {
"use strict";
angular.module("app-trips", ['ngSanitize']);
})();
BTW - supposedly according to the course I'm following, I don't need ['ngSanitize'] yet, but without it it doesn't even show the DIVs.
EDIT: as #jellyraptor noticed , I had a typo with = instead of :
EDIT 2 :
It was the typo + the [ngSanitize] which I really didn't needed. I fixed the typo and passed an empty array and everything works. Thanks all
Either Angular isn't loading or it is encountering an error. Bring up the dev tools with F12 and see if there are errors in the console. Also in the console, you can type 'angular' and hit enter and if it reports that angular is undefined then angular is not loading properly.
Because you are using controllerAs syntax and here the variable is vm. so for access scope object use vm instead of tripsController
<tr ng-repeat="trip in vm.trips">
<td>{{ trip.name }}</td>
<td>{{ trip.created }}</td>
</tr>
(function() {
"use strict";
angular.module("app-trips", []);
})();
angular.module("app-trips")
.controller("tripsController", tripsController);
function tripsController() {
var vm = this;
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created: new Date()
}];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.min.js"></script>
<div ng-app="app-trips" ng-controller="tripsController as vm" class="col-md-6 col-md-offset-3">
<table class="table table-responsive table-striped">
<tr ng-repeat="trip in vm.trips">
<td>{{ trip.name }}</td>
<td>{{ trip.created }}</td>
</tr>
</table>
</div>
You put an equals sign in your trips array's second object's 'created' attribute.
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created = new Date()
}];
should be
vm.trips = [{
name: "US Trip",
created: new Date()
}, {
name: "World Trip",
created: new Date()
}];

AngularJS can not read property id of undefined Error

I am getting the error "can not read property id of undefined" in AngularJS.
We have two API End point,
i> GET http://127.0.0.1:8088/api/information/ to fetch the data from JSON.
ii> DELETE http://127.0.0.1:8088/api/information/:id to delete the data of that particular id.
I have created a table, where datas will display in row. There is a checkbox to select row and a Delete button.
I am performing three operations,
i> Ftech the data in table.
ii> Click on checkbox to select that row.
iii> Click on the DELETE button to delete that data from display and hit the DELETE api end point to delete from server too.
iv>Refresh the page and fetch the data again.
Here is the JSON :-
{
"1": {
"venture": "XYZ Informatics",
"member": [
{
"name": "abcd",
"email": "abcd#gmail.com"
}
],
"message": "This is good day",
"isclicked": false
},
"2": {
"venture": "BBC Informatics",
"member": [
{
"name": "xyz",
"email": "xyz#gmail.com"
}
],
"message": "This is bad day",
"isclicked": true
}
}
Here is the code :-
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 15px;
}
</style>
</head>
<body>
<div ng-app="MyApp" ng-controller="displayController">
<table style="width:100%">
<tr ng-repeat="data in datas">
<td>
<input type="checkbox" ng-model="data.clicked">
</td>
<td>{{ data.id }}</td>
<td>{{ data.venture }}</td>
<td>{{ data.message }}</td>
</tr>
</table>
<button ng-click="delete()">DELETE</button>
</div>
<script>
angular.module('MyApp', [])
.controller('displayController', function($scope, $http) {
var url = "http://127.0.0.1:8088/api/information";
$http.get(url).success(function (response) {
$scope.datas = response;
});
//To Delete
$scope.delete=function(){
angular.forEach($scope.datas, function(val, key){
if(val.clicked){
delete $scope.datas[key]
var userId = $scope.data.id; //It is coming from {{ data.id }}
$http.delete('http://127.0.0.1:8088/api/information/:' + userId) //DELETE API end point
.success(function (response) {
$scope.refresh(); //Refresher function
});
$scope.refresh = function(){
var url = "http://127.0.0.1:8088/api/information"; //Fetch the updated data
$http.get(url).success(function (response) {
$scope.datas = response;
});
}
}
})
}
});
</script>
</body>
</html>
Not near a computer to properly test your code, but a first read left me with this: When you do delete $scope.datas[key], you are destroying the data object. So when you try to assign userId, the object you are trying to access doesn't exist. My recommendation would be to only do a local item removal on a successful server DELETE. Try moving delete $scope.datas[key] into the success function.
On a separate note, .success() is deprecated, and it is preferred to use the ES6 Promise compliant .then(successfn, errorfn) form. See more here.

angular ng-repeat needs changes in data that is obtained from json

I have a JSON object that does not have proper data. So i want to replace the obtained value with one from a lookup table, but I'm not sure how to replace the value of the data corresponding to the lookup table.
lookupTable = {
"pizza": function() {
console.log("food");
},
"house": function() {
console.log("building");
},
"air": function() {
console.log("nothing");
}
};
$scope.value =lookupTable["pizza"]()
my html file has
<tr ng-repeat="x in names">
<td>{{ x.lookupTable["pizza"]() }}</td>
My code is at http://plnkr.co/edit/w4lOFVRo9vSi8vqfbpXV?p=preview
Any help is appreciated!
Here are some problems in your code from the link you provided:
Functions on the lookupTable is not returning anything as pointed out in the previous answers.
lookupTable is not a property of $scope.names so using x.lookupTable is invalid.
To make it work, you should:
The functions from lookupTable should return the actual values instead of using console.log
Bind lookupTable to $scope
Use lookupTable directly inside the view as it is bound to $scope
Here is the relevant code:
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name]() }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
$scope.lookupTable = {
"pizza": function() {
return 'food';
},
"house": function() {
return 'building';
},
"air": function() {
return "nothing";
}
};
});
</script>
Your code is very confused. I tried to edit your plunker, maybe is easier to see that to explain.
<!DOCTYPE html>
<html>
<scriptsrc="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name] }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
lookupTable = {
"pizza": "food",
"house": "building",
"air": "nothing"
};
$scope.lookupTable = lookupTable;
$scope.value = lookupTable["pizza"]
console.log(lookupTable["house"])
});
</script>
Looking at your code, I am not sure what you want to achieve.
The ng-repeat gives you three objects out of names, but none of them has a lookupTable member, so {{ x.lookupTable["pizza"] }} fails silently.
You can make it visible, if you just bind to {{ x }}

trying to display json data with angularjs ng-repeat not working

I've seen so many ways to do this, but most are pretty old and I want to make sure I'm doing this correctly. Right now, the way I'm using isn't working and I feel like I'm missing something.
I'm getting the JSON back fine, I just need to get it to display in a table after I click the button.
Here is the JSON. This is how I'm going to get it from our server, I can't add any "var JSON =" or add any scope like "$scope.carrier" to the data, unless there's a way to add it after I've fetched the data.
{
"carrier":
[
{
"entity": "carrier",
"id": 1,
"parentEntity": "ORMS",
"value": "Medica"
}, {
"entity": "carrier",
"id": 2,
"parentEntity": "ORMS",
"value": "UHG"
}, {
"entity": "carrier",
"id": 3,
"parentEntity": "ORMS",
"value": "Optum"
}, {
"entity": "carrier",
"id": 4,
"parentEntity": "ORMS",
"value": "Insight"
}, {
"entity": "carrier",
"id": 5,
"parentEntity": "ORMS",
"value": "Insight"
}
]
}
Here is the app.js file to bring back the JSON data:
var app = angular.module('myTestApp', []);
app.controller('myController', ['$scope', '$http', function($scope, $http) {
var url = 'test.json';
$scope.clickButton = function() {
$http.get(url).success(function(data) {
console.log(data);
});
}
}]);
And then of course the HTML:
<div class="col-lg-12 text-center">
<button type=button class="btn btn-primary load" ng-click="clickButton()">Click!</button>
<table class="">
<tbody ng-repeat="carrier in carriers">
<tr>
<td>
<h3 class="">{{ module.entity }}</h3>
<h3 class="">{{ module.id }}</h3>
<h3 class="">{{ module.parentEntity }}</h3>
<h3 class="">{{ module.value }}</h3>
</td>
</tr>
</tbody>
</table>
</div>
I'm also wondering if I can use the ng-grid to put this in a table. I know they just upgraded it to ui grid so I'm not sure if this is still a feasible approach.
Also, I'm not getting errors, the data just won't display in the table right now. All I know is its returning the data properly, just not displaying in the table.
Any help is appreciated.
I looked at your plunker seems like you need to:
add angular script
wire the app and the controller
your variable in the repeater is wrong, I change it
take a look to this fixed plunker:
http://plnkr.co/edit/TAjnUCMOBxQTC6lNJL8j?p=preview
$scope.clickButton = function() {
$http.get(url).success(function(returnValue) {
alert(JSON.stringify(returnValue.carrier));
$scope.carriers = returnValue.carrier;
});
}
You never assign the value of the returned array to $scope.carriers.
At the line where you say console.log(data); add this:
$scope.carriers = data.data;
Here is the updated clickButton function (with a variable name change to reduce confusion):
$scope.clickButton = function() {
$http.get(url).success(function(returnValue) {
$scope.carriers = returnValue.data;
});
};

AngularJS Multidimensional JSON

I know this is a bit basic but i'm struggling to get my head round it, I have a web service that returns the follow JSON:
[{"search_id":"1","user_id":"1","all_words":"php","not_words":"C++","one_words":"java","created_at":null,"updated_at":null,"search_name":null},{"search_id":"2","user_id":"1","all_words":"second","not_words":"not","one_words":"one","created_at":null,"updated_at":null,"search_name":null}]
So when it gets to angular I end up with the following:
Array[2]
0: Object
$$hashKey: "object:5"
all_words: "php"
created_at: null
not_words: "C++"
one_words: "java"
search_id: "1"
search_name: null
updated_at: null
user_id: "1"
__proto__:
1: Object
$$hashKey: "object:6"
all_words: "second"
created_at: null
not_words: "not"
one_words: "one"
search_id: "2"
search_name: null
updated_at: null
user_id: "1"
__proto__:
Which is a real pain to work with in ng-repeat, how would I go about being able to access it like so(rough example)
ng-repeat="item in items"
{{ item.search_id }}
to be clear the only way I can get data from it is by doing:
<tr ng-repeat="items in data">
<td ng-repeat="(key, value) in items"> </td>
</tr>
Controller code is here:
testAPI.getSearches().then(function (data) {
$scope.data= testAPI.searchList();
console.log($scope.data);
}, function (error) {
alert("Error in getSearches");
});
getsearches as follows, searchList returns the searches variable:
getSearches: function() {
var deferred = $q.defer();
$http({
url: 'http://localhost/api/api/tray/search/list'
}).success(function (data) {
searches = data;
console.log(data);
deferred.resolve(data);
}).error(function (data) {
alert('Error');
deferred.reject(data);
});
return deferred.promise;
},
Hrm thanks for the responses guys but the plain "item in data" does not work in my case I have to use (key,value) in items inside a nested ng repeat, any ideas what i'm missing?
By the way not sure if this matters put the HTML is inside a partial and i'm using ui router for the navigation?
UPDATE
Thank you all very much for your help, looks like this problem was caused by a typo on a containing HTML element and the controller not being setup properly because I messed up the ui router setup. Once i've had a chance to make sure i've missed nothing else i'll post back.
This seems to be working fine. Just make sure you're data is tied to your $scope.
http://jsfiddle.net/f4zdfh72/
function MyCtrl($scope) {
$scope.data = [{
"search_id": "1",
"user_id": "1",
"all_words": "php",
"not_words": "C++",
"one_words": "java",
"created_at": null,
"updated_at": null,
"search_name": null
}, {
"search_id": "2",
"user_id": "1",
"all_words": "second",
"not_words": "not",
"one_words": "one",
"created_at": null,
"updated_at": null,
"search_name": null
}]
}
<div ng-controller="MyCtrl">
<div ng-repeat='item in data'>
THIS IS DATA: {{item.one_words}}
</div>
</div>
Note: run it in the JSFiddle. Stack snippet is just for code preview
works fine for me: http://plnkr.co/edit/ubiWcF3CemeKo6dzkvNC?p=preview
var app = angular.module("myApp", []);
app.controller('myCtrl', ['$scope', function($scope){
$scope.data = JSON.parse('[{"search_id":"1","user_id":"1","all_words":"php","not_words":"C++","one_words":"java","created_at":null,"updated_at":null,"search_name":null},{"search_id":"2","user_id":"1","all_words":"second","not_words":"not","one_words":"one","created_at":null,"updated_at":null,"search_name":null}]')
}]);
Maybe I am missunderstanding, but this should actually work. Plunker The Example includes the Controller As and $scope approaches.
Controller
angular
.module("app", [])
.controller("MainController", ['$scope', function($scope) {
var vm = this;
var json = '[{"search_id":"1","user_id":"1","all_words":"php","not_words":"C++","one_words":"java","created_at":null,"updated_at":null,"search_name":null},{"search_id":"2","user_id":"1","all_words":"second","not_words":"not","one_words":"one","created_at":null,"updated_at":null,"search_name":null}]';
vm.items = JSON.parse(json);
$scope.items = JSON.parse(json);
}]);
html
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="MainController as vm">
<h1>Items Controller As</h1>
<div ng-repeat="item in vm.items">
{{ item.search_id }}
</div>
<h1>Items $scope</h1>
<div ng-repeat="item in items">
{{ item.search_id }}
</div>
<script data-require="angular.js#1.3.6" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script>
<script src="script.js"></script>
</body>
</html>
Edit:
Added my comment from above.
Why do you use two nested ng-repeats? I guess one object of the array should be one row in the table. Therefore
<tr ng-repeat="item in data">
...
<td>{{item.search_name}}</td>
...
</tr>
should work. Unless you need the keys of the object, than you need (key, value).

Categories